1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use super::*;

mod display;

#[doc = include_str!("readme.md")]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ForLoop {
    /// `for pattern`
    pub pattern: PatternNode,
    /// `in iterator`
    pub iterator: ExpressionKind,
    /// `if condition`
    pub condition: Option<ExpressionKind>,
    /// `#label`
    pub label: Option<IdentifierNode>,
    /// `{ body }`
    pub body: StatementBlock,
    /// The range of the node
    pub span: Range<u32>,
}

impl ValkyrieNode for ForLoop {
    fn get_range(&self) -> Range<usize> {
        Range { start: self.span.start as usize, end: self.span.end as usize }
    }
}

/// `for ref a, mut b in {...}`
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ForBarePattern {
    /// The bare tuple pattern
    pub pattern: Vec<ArgumentKey>,
    /// The range of the node
    pub span: Range<u32>,
}

impl ForLoop {
    pub fn standardization(self, iterator: IdentifierNode) -> (VariableDeclaration, LoopStatement) {
        let var = VariableDeclaration { identifier: iterator, type_hint: None, body: None };
        let lops = LoopStatement { label: self.label, terms: vec![] };
        (var, lops)
    }
}

impl ForBarePattern {
    /// Convert this bare pattern into tuple pattern
    #[allow(clippy::wrong_self_convention)]
    pub fn as_pattern_expression(self) -> PatternNode {
        TuplePatternNode {
            bind: None,
            name: None,
            terms: self.pattern.into_iter().map(PatternNode::from).collect(),
            span: self.span,
        }
        .into()
    }
}