ara_parser/tree/statement/
loop.rs

1use bincode::Decode;
2use bincode::Encode;
3use schemars::JsonSchema;
4use serde::Deserialize;
5use serde::Serialize;
6
7use crate::tree::comment::CommentGroup;
8use crate::tree::expression::literal::LiteralInteger;
9use crate::tree::expression::Expression;
10use crate::tree::statement::block::BlockStatement;
11use crate::tree::token::Keyword;
12use crate::tree::utils::CommaSeparated;
13use crate::tree::variable::Variable;
14use crate::tree::Node;
15
16#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
17#[serde(rename_all = "snake_case")]
18pub struct ForeachStatement {
19    pub comments: CommentGroup,
20    pub foreach: Keyword,
21    pub iterator: ForeachIteratorStatement,
22    pub block: BlockStatement,
23    pub r#else: Option<Keyword>,
24    pub else_block: Option<BlockStatement>,
25}
26
27#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
28#[serde(rename_all = "snake_case")]
29pub enum ForeachIteratorStatement {
30    Value {
31        expression: Expression,
32        r#as: Keyword,
33        value: Variable,
34    },
35    ParenthesizedValue {
36        left_parenthesis: usize,
37        expression: Expression,
38        r#as: Keyword,
39        value: Variable,
40        right_parenthesis: usize,
41    },
42    KeyAndValue {
43        expression: Expression,
44        r#as: Keyword,
45        key: Variable,
46        double_arrow: usize,
47        value: Variable,
48    },
49    ParenthesizedKeyAndValue {
50        left_parenthesis: usize,
51        expression: Expression,
52        r#as: Keyword,
53        key: Variable,
54        double_arrow: usize,
55        value: Variable,
56        right_parenthesis: usize,
57    },
58}
59
60#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
61#[serde(rename_all = "snake_case")]
62pub struct ForStatement {
63    pub comments: CommentGroup,
64    pub r#for: Keyword,
65    pub iterator: ForIteratorStatement,
66    pub block: BlockStatement,
67}
68
69#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
70#[serde(rename_all = "snake_case")]
71pub enum ForIteratorStatement {
72    Standalone {
73        initializations: CommaSeparated<Expression>,
74        initializations_semicolon: usize,
75        conditions: CommaSeparated<Expression>,
76        conditions_semicolon: usize,
77        r#loop: CommaSeparated<Expression>,
78    },
79    Parenthesized {
80        left_parenthesis: usize,
81        initializations: CommaSeparated<Expression>,
82        initializations_semicolon: usize,
83        conditions: CommaSeparated<Expression>,
84        conditions_semicolon: usize,
85        r#loop: CommaSeparated<Expression>,
86        right_parenthesis: usize,
87    },
88}
89
90#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
91#[serde(rename_all = "snake_case")]
92pub struct DoWhileStatement {
93    pub comments: CommentGroup,
94    pub r#do: Keyword,
95    pub block: BlockStatement,
96    pub r#while: Keyword,
97    pub conditions: CommaSeparated<Expression>,
98    pub semicolon: usize,
99}
100
101#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
102#[serde(rename_all = "snake_case")]
103pub struct WhileStatement {
104    pub comments: CommentGroup,
105    pub r#while: Keyword,
106    pub conditions: CommaSeparated<Expression>,
107    pub block: BlockStatement,
108}
109
110#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
111#[serde(rename_all = "snake_case")]
112pub struct BreakStatement {
113    pub comments: CommentGroup,
114    pub r#break: Keyword,
115    pub level: Option<LiteralInteger>,
116    pub semicolon: usize,
117}
118
119#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
120#[serde(rename_all = "snake_case")]
121pub struct ContinueStatement {
122    pub comments: CommentGroup,
123    pub r#continue: Keyword,
124    pub level: Option<LiteralInteger>,
125    pub semicolon: usize,
126}
127
128impl ForeachIteratorStatement {
129    pub fn expression(&self) -> &Expression {
130        match &self {
131            Self::Value { expression, .. } => expression,
132            Self::ParenthesizedValue { expression, .. } => expression,
133            Self::KeyAndValue { expression, .. } => expression,
134            Self::ParenthesizedKeyAndValue { expression, .. } => expression,
135        }
136    }
137
138    pub fn key(&self) -> Option<&Variable> {
139        match &self {
140            Self::Value { .. } => None,
141            Self::ParenthesizedValue { .. } => None,
142            Self::KeyAndValue { key, .. } => Some(key),
143            Self::ParenthesizedKeyAndValue { key, .. } => Some(key),
144        }
145    }
146
147    pub fn value(&self) -> &Variable {
148        match &self {
149            Self::Value { value, .. } => value,
150            Self::ParenthesizedValue { value, .. } => value,
151            Self::KeyAndValue { value, .. } => value,
152            Self::ParenthesizedKeyAndValue { value, .. } => value,
153        }
154    }
155}
156
157impl Node for ForeachStatement {
158    fn comments(&self) -> Option<&CommentGroup> {
159        Some(&self.comments)
160    }
161
162    fn initial_position(&self) -> usize {
163        self.foreach.initial_position()
164    }
165
166    fn final_position(&self) -> usize {
167        self.block.final_position()
168    }
169
170    fn children(&self) -> Vec<&dyn Node> {
171        let mut children: Vec<&dyn Node> = vec![&self.foreach, &self.iterator, &self.block];
172
173        if let Some(r#else) = &self.r#else {
174            children.push(r#else);
175        }
176
177        if let Some(else_block) = &self.else_block {
178            children.push(else_block);
179        }
180
181        children
182    }
183
184    fn get_description(&self) -> String {
185        "foreach statement".to_string()
186    }
187}
188
189impl Node for ForeachIteratorStatement {
190    fn comments(&self) -> Option<&CommentGroup> {
191        None
192    }
193
194    fn initial_position(&self) -> usize {
195        match &self {
196            Self::Value { expression, .. } | Self::KeyAndValue { expression, .. } => {
197                expression.initial_position()
198            }
199            Self::ParenthesizedValue {
200                left_parenthesis, ..
201            }
202            | Self::ParenthesizedKeyAndValue {
203                left_parenthesis, ..
204            } => *left_parenthesis,
205        }
206    }
207
208    fn final_position(&self) -> usize {
209        match &self {
210            Self::Value { value, .. } | Self::KeyAndValue { value, .. } => value.final_position(),
211            Self::ParenthesizedValue {
212                right_parenthesis, ..
213            }
214            | Self::ParenthesizedKeyAndValue {
215                right_parenthesis, ..
216            } => right_parenthesis + 1,
217        }
218    }
219
220    fn children(&self) -> Vec<&dyn Node> {
221        match &self {
222            Self::Value {
223                expression,
224                r#as,
225                value,
226                ..
227            }
228            | Self::ParenthesizedValue {
229                expression,
230                r#as,
231                value,
232                ..
233            } => {
234                vec![expression, r#as, value]
235            }
236            Self::KeyAndValue {
237                expression,
238                r#as,
239                key,
240                value,
241                ..
242            }
243            | Self::ParenthesizedKeyAndValue {
244                expression,
245                r#as,
246                key,
247                value,
248                ..
249            } => {
250                vec![expression, r#as, key, value]
251            }
252        }
253    }
254
255    fn get_description(&self) -> String {
256        "foreach iterator".to_string()
257    }
258}
259
260impl Node for ForStatement {
261    fn comments(&self) -> Option<&CommentGroup> {
262        Some(&self.comments)
263    }
264
265    fn initial_position(&self) -> usize {
266        self.r#for.initial_position()
267    }
268
269    fn final_position(&self) -> usize {
270        self.block.final_position()
271    }
272
273    fn children(&self) -> Vec<&dyn Node> {
274        vec![&self.r#for, &self.iterator, &self.block]
275    }
276
277    fn get_description(&self) -> String {
278        "for statement".to_string()
279    }
280}
281
282impl Node for ForIteratorStatement {
283    fn comments(&self) -> Option<&CommentGroup> {
284        None
285    }
286
287    fn initial_position(&self) -> usize {
288        match &self {
289            Self::Standalone {
290                initializations,
291                initializations_semicolon,
292                ..
293            } => {
294                if let Some(expression) = initializations.inner.first() {
295                    expression.initial_position()
296                } else {
297                    *initializations_semicolon
298                }
299            }
300            Self::Parenthesized {
301                left_parenthesis, ..
302            } => *left_parenthesis,
303        }
304    }
305
306    fn final_position(&self) -> usize {
307        match &self {
308            Self::Standalone {
309                conditions_semicolon,
310                r#loop,
311                ..
312            } => {
313                if let Some(expression) = r#loop.inner.last() {
314                    expression.final_position()
315                } else {
316                    conditions_semicolon + 1
317                }
318            }
319            Self::Parenthesized {
320                right_parenthesis, ..
321            } => right_parenthesis + 1,
322        }
323    }
324
325    fn children(&self) -> Vec<&dyn Node> {
326        match &self {
327            Self::Standalone {
328                initializations,
329                conditions,
330                r#loop,
331                ..
332            }
333            | Self::Parenthesized {
334                initializations,
335                conditions,
336                r#loop,
337                ..
338            } => {
339                let mut children: Vec<&dyn Node> = vec![];
340
341                for expression in &initializations.inner {
342                    children.push(expression);
343                }
344
345                for expression in &conditions.inner {
346                    children.push(expression);
347                }
348
349                for expression in &r#loop.inner {
350                    children.push(expression);
351                }
352
353                children
354            }
355        }
356    }
357
358    fn get_description(&self) -> String {
359        "for iterator statement".to_string()
360    }
361}
362
363impl Node for DoWhileStatement {
364    fn comments(&self) -> Option<&CommentGroup> {
365        Some(&self.comments)
366    }
367
368    fn initial_position(&self) -> usize {
369        self.r#do.initial_position()
370    }
371
372    fn final_position(&self) -> usize {
373        self.semicolon + 1
374    }
375
376    fn children(&self) -> Vec<&dyn Node> {
377        let mut children: Vec<&dyn Node> = vec![&self.r#do, &self.block, &self.r#while];
378
379        for condition in &self.conditions.inner {
380            children.push(condition);
381        }
382
383        children
384    }
385
386    fn get_description(&self) -> String {
387        "do-while statement".to_string()
388    }
389}
390
391impl Node for WhileStatement {
392    fn comments(&self) -> Option<&CommentGroup> {
393        Some(&self.comments)
394    }
395
396    fn initial_position(&self) -> usize {
397        self.r#while.initial_position()
398    }
399
400    fn final_position(&self) -> usize {
401        self.block.final_position()
402    }
403
404    fn children(&self) -> Vec<&dyn Node> {
405        let mut children: Vec<&dyn Node> = vec![&self.r#while, &self.block];
406
407        for condition in &self.conditions.inner {
408            children.push(condition);
409        }
410
411        children
412    }
413
414    fn get_description(&self) -> String {
415        "while statement".to_string()
416    }
417}
418
419impl Node for BreakStatement {
420    fn comments(&self) -> Option<&CommentGroup> {
421        Some(&self.comments)
422    }
423
424    fn initial_position(&self) -> usize {
425        self.r#break.initial_position()
426    }
427
428    fn final_position(&self) -> usize {
429        self.semicolon + 1
430    }
431
432    fn children(&self) -> Vec<&dyn Node> {
433        if let Some(level) = &self.level {
434            vec![&self.r#break, level]
435        } else {
436            vec![&self.r#break]
437        }
438    }
439
440    fn get_description(&self) -> String {
441        "break statement".to_string()
442    }
443}
444
445impl Node for ContinueStatement {
446    fn comments(&self) -> Option<&CommentGroup> {
447        Some(&self.comments)
448    }
449
450    fn initial_position(&self) -> usize {
451        self.r#continue.initial_position()
452    }
453
454    fn final_position(&self) -> usize {
455        self.semicolon + 1
456    }
457
458    fn children(&self) -> Vec<&dyn Node> {
459        if let Some(level) = &self.level {
460            vec![&self.r#continue, level]
461        } else {
462            vec![&self.r#continue]
463        }
464    }
465
466    fn get_description(&self) -> String {
467        "continue statement".to_string()
468    }
469}