vex-ast 0.2.4__py3-none-any.whl → 0.2.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. vex_ast/README.md +101 -51
  2. vex_ast/READMEAPI.md +133 -318
  3. vex_ast/__init__.py +81 -72
  4. vex_ast/ast/README.md +87 -87
  5. vex_ast/ast/__init__.py +74 -74
  6. vex_ast/ast/core.py +71 -71
  7. vex_ast/ast/expressions.py +276 -276
  8. vex_ast/ast/interfaces.py +208 -208
  9. vex_ast/ast/literals.py +80 -80
  10. vex_ast/ast/navigator.py +225 -225
  11. vex_ast/ast/operators.py +135 -135
  12. vex_ast/ast/statements.py +351 -351
  13. vex_ast/ast/validators.py +121 -120
  14. vex_ast/ast/vex_nodes.py +279 -279
  15. vex_ast/parser/README.md +47 -47
  16. vex_ast/parser/__init__.py +26 -26
  17. vex_ast/parser/factory.py +190 -190
  18. vex_ast/parser/interfaces.py +34 -34
  19. vex_ast/parser/python_parser.py +831 -786
  20. vex_ast/registry/README.md +107 -29
  21. vex_ast/registry/__init__.py +51 -51
  22. vex_ast/registry/api.py +190 -155
  23. vex_ast/registry/categories.py +179 -136
  24. vex_ast/registry/functions/__init__.py +10 -10
  25. vex_ast/registry/functions/constructors.py +71 -0
  26. vex_ast/registry/functions/display.py +146 -146
  27. vex_ast/registry/functions/drivetrain.py +163 -163
  28. vex_ast/registry/functions/initialize.py +31 -28
  29. vex_ast/registry/functions/motor.py +140 -140
  30. vex_ast/registry/functions/sensors.py +194 -194
  31. vex_ast/registry/functions/timing.py +103 -103
  32. vex_ast/registry/language_map.py +77 -77
  33. vex_ast/registry/registry.py +164 -153
  34. vex_ast/registry/signature.py +269 -191
  35. vex_ast/registry/simulation_behavior.py +8 -8
  36. vex_ast/registry/validation.py +43 -43
  37. vex_ast/serialization/__init__.py +37 -37
  38. vex_ast/serialization/json_deserializer.py +284 -275
  39. vex_ast/serialization/json_serializer.py +148 -148
  40. vex_ast/serialization/schema.py +492 -470
  41. vex_ast/types/README.md +78 -26
  42. vex_ast/types/__init__.py +140 -140
  43. vex_ast/types/base.py +83 -83
  44. vex_ast/types/enums.py +122 -97
  45. vex_ast/types/objects.py +64 -64
  46. vex_ast/types/primitives.py +68 -68
  47. vex_ast/types/type_checker.py +31 -31
  48. vex_ast/utils/README.md +39 -39
  49. vex_ast/utils/__init__.py +37 -37
  50. vex_ast/utils/errors.py +112 -112
  51. vex_ast/utils/source_location.py +38 -38
  52. vex_ast/utils/type_definitions.py +8 -8
  53. vex_ast/visitors/README.md +49 -49
  54. vex_ast/visitors/__init__.py +27 -27
  55. vex_ast/visitors/analyzer.py +102 -102
  56. vex_ast/visitors/base.py +133 -133
  57. vex_ast/visitors/printer.py +196 -146
  58. {vex_ast-0.2.4.dist-info → vex_ast-0.2.6.dist-info}/METADATA +206 -174
  59. vex_ast-0.2.6.dist-info/RECORD +64 -0
  60. vex_ast-0.2.4.dist-info/RECORD +0 -63
  61. {vex_ast-0.2.4.dist-info → vex_ast-0.2.6.dist-info}/WHEEL +0 -0
  62. {vex_ast-0.2.4.dist-info → vex_ast-0.2.6.dist-info}/licenses/LICENSE +0 -0
  63. {vex_ast-0.2.4.dist-info → vex_ast-0.2.6.dist-info}/top_level.txt +0 -0
vex_ast/ast/statements.py CHANGED
@@ -1,351 +1,351 @@
1
- """Statement nodes for the AST."""
2
-
3
- from typing import Dict, List, Optional, Union, cast, Any
4
-
5
- from .interfaces import IAstNode, IExpression, IStatement, IVisitor, T_VisitorResult, IAssignment
6
- from .core import Statement, Expression
7
- from .expressions import Identifier
8
- from ..utils.source_location import SourceLocation
9
-
10
- class ExpressionStatement(Statement):
11
- """An expression used as a statement."""
12
-
13
- _fields = ('expression',)
14
-
15
- def __init__(self, expression: IExpression, location: Optional[SourceLocation] = None):
16
- super().__init__(location)
17
- self.expression = expression
18
- if isinstance(expression, Expression):
19
- expression.set_parent(self)
20
-
21
- def get_children(self) -> List[IAstNode]:
22
- return [cast(IAstNode, self.expression)]
23
-
24
- def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
25
- return visitor.visit_expressionstatement(self)
26
-
27
- def get_expression(self) -> IExpression:
28
- """Get the expression."""
29
- return self.expression
30
-
31
- class Assignment(Statement, IAssignment):
32
- """An assignment statement (target = value)."""
33
-
34
- _fields = ('target', 'value')
35
-
36
- def __init__(self, target: IExpression, value: IExpression,
37
- location: Optional[SourceLocation] = None):
38
- super().__init__(location)
39
- self.target = target
40
- self.value = value
41
- if isinstance(target, Expression):
42
- target.set_parent(self)
43
- if isinstance(value, Expression):
44
- value.set_parent(self)
45
-
46
- def get_children(self) -> List[IAstNode]:
47
- return [cast(IAstNode, self.target), cast(IAstNode, self.value)]
48
-
49
- def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
50
- return visitor.visit_assignment(self)
51
-
52
- def get_target(self) -> IExpression:
53
- """Get the assignment target."""
54
- return self.target
55
-
56
- def get_value(self) -> IExpression:
57
- """Get the assigned value."""
58
- return self.value
59
-
60
- class Argument(Statement):
61
- """A function argument in a definition."""
62
-
63
- _fields = ('name', 'annotation', 'default')
64
-
65
- def __init__(self, name: str, annotation: Optional[IExpression] = None,
66
- default: Optional[IExpression] = None,
67
- location: Optional[SourceLocation] = None):
68
- super().__init__(location)
69
- self.name = name
70
- self.annotation = annotation
71
- self.default = default
72
-
73
- if isinstance(annotation, Expression):
74
- annotation.set_parent(self)
75
- if isinstance(default, Expression):
76
- default.set_parent(self)
77
-
78
- def get_children(self) -> List[IAstNode]:
79
- result: List[IAstNode] = []
80
- if self.annotation:
81
- result.append(cast(IAstNode, self.annotation))
82
- if self.default:
83
- result.append(cast(IAstNode, self.default))
84
- return result
85
-
86
- def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
87
- return visitor.visit_argument(self)
88
-
89
- def get_name(self) -> str:
90
- """Get the argument name."""
91
- return self.name
92
-
93
- def get_annotation(self) -> Optional[IExpression]:
94
- """Get the type annotation, if any."""
95
- return self.annotation
96
-
97
- def get_default(self) -> Optional[IExpression]:
98
- """Get the default value, if any."""
99
- return self.default
100
-
101
- class FunctionDefinition(Statement):
102
- """A function definition."""
103
-
104
- _fields = ('name', 'args', 'body', 'return_annotation')
105
-
106
- def __init__(self, name: str, args: List[Argument], body: List[IStatement],
107
- return_annotation: Optional[IExpression] = None,
108
- location: Optional[SourceLocation] = None):
109
- super().__init__(location)
110
- self.name = name
111
- self.args = args
112
- self.body = body
113
- self.return_annotation = return_annotation
114
-
115
- # Set parent references
116
- for arg in self.args:
117
- if isinstance(arg, Statement):
118
- arg.set_parent(self)
119
-
120
- for stmt in self.body:
121
- if isinstance(stmt, Statement):
122
- stmt.set_parent(self)
123
-
124
- if isinstance(return_annotation, Expression):
125
- return_annotation.set_parent(self)
126
-
127
- def get_children(self) -> List[IAstNode]:
128
- result: List[IAstNode] = cast(List[IAstNode], self.args)
129
- result.extend(cast(List[IAstNode], self.body))
130
- if self.return_annotation:
131
- result.append(cast(IAstNode, self.return_annotation))
132
- return result
133
-
134
- def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
135
- return visitor.visit_functiondefinition(self)
136
-
137
- def get_name(self) -> str:
138
- """Get the function name."""
139
- return self.name
140
-
141
- def get_arguments(self) -> List[Argument]:
142
- """Get the function arguments."""
143
- return self.args
144
-
145
- def get_body(self) -> List[IStatement]:
146
- """Get the function body."""
147
- return self.body
148
-
149
- def get_return_annotation(self) -> Optional[IExpression]:
150
- """Get the return type annotation, if any."""
151
- return self.return_annotation
152
-
153
- def add_statement(self, statement: IStatement) -> None:
154
- """Add a statement to the function body."""
155
- self.body.append(statement)
156
- if isinstance(statement, Statement):
157
- statement.set_parent(self)
158
-
159
- class IfStatement(Statement):
160
- """An if statement with optional else branch."""
161
-
162
- _fields = ('test', 'body', 'orelse')
163
-
164
- def __init__(self, test: IExpression, body: List[IStatement],
165
- orelse: Optional[Union[List[IStatement], 'IfStatement']] = None,
166
- location: Optional[SourceLocation] = None):
167
- super().__init__(location)
168
- self.test = test
169
- self.body = body
170
- self.orelse = orelse
171
-
172
- # Set parent references
173
- if isinstance(test, Expression):
174
- test.set_parent(self)
175
-
176
- for stmt in self.body:
177
- if isinstance(stmt, Statement):
178
- stmt.set_parent(self)
179
-
180
- if isinstance(self.orelse, list):
181
- for stmt in self.orelse:
182
- if isinstance(stmt, Statement):
183
- stmt.set_parent(self)
184
- elif isinstance(self.orelse, Statement):
185
- self.orelse.set_parent(self)
186
-
187
- def get_children(self) -> List[IAstNode]:
188
- result: List[IAstNode] = [cast(IAstNode, self.test)]
189
- result.extend(cast(List[IAstNode], self.body))
190
- if isinstance(self.orelse, list):
191
- result.extend(cast(List[IAstNode], self.orelse))
192
- elif self.orelse:
193
- result.append(cast(IAstNode, self.orelse))
194
- return result
195
-
196
- def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
197
- return visitor.visit_ifstatement(self)
198
-
199
- def get_test(self) -> IExpression:
200
- """Get the test condition."""
201
- return self.test
202
-
203
- def get_body(self) -> List[IStatement]:
204
- """Get the if body."""
205
- return self.body
206
-
207
- def get_else(self) -> Optional[Union[List[IStatement], 'IfStatement']]:
208
- """Get the else branch, if any."""
209
- return self.orelse
210
-
211
- def add_statement(self, statement: IStatement) -> None:
212
- """Add a statement to the if body."""
213
- self.body.append(statement)
214
- if isinstance(statement, Statement):
215
- statement.set_parent(self)
216
-
217
- class WhileLoop(Statement):
218
- """A while loop."""
219
-
220
- _fields = ('test', 'body')
221
-
222
- def __init__(self, test: IExpression, body: List[IStatement],
223
- location: Optional[SourceLocation] = None):
224
- super().__init__(location)
225
- self.test = test
226
- self.body = body
227
-
228
- # Set parent references
229
- if isinstance(test, Expression):
230
- test.set_parent(self)
231
-
232
- for stmt in self.body:
233
- if isinstance(stmt, Statement):
234
- stmt.set_parent(self)
235
-
236
- def get_children(self) -> List[IAstNode]:
237
- result: List[IAstNode] = [cast(IAstNode, self.test)]
238
- result.extend(cast(List[IAstNode], self.body))
239
- return result
240
-
241
- def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
242
- return visitor.visit_whileloop(self)
243
-
244
- def get_test(self) -> IExpression:
245
- """Get the test condition."""
246
- return self.test
247
-
248
- def get_body(self) -> List[IStatement]:
249
- """Get the loop body."""
250
- return self.body
251
-
252
- def add_statement(self, statement: IStatement) -> None:
253
- """Add a statement to the loop body."""
254
- self.body.append(statement)
255
- if isinstance(statement, Statement):
256
- statement.set_parent(self)
257
-
258
- class ForLoop(Statement):
259
- """A for loop (for target in iterable)."""
260
-
261
- _fields = ('target', 'iterable', 'body')
262
-
263
- def __init__(self, target: IExpression, iterable: IExpression,
264
- body: List[IStatement], location: Optional[SourceLocation] = None):
265
- super().__init__(location)
266
- self.target = target
267
- self.iterable = iterable
268
- self.body = body
269
-
270
- # Set parent references
271
- if isinstance(target, Expression):
272
- target.set_parent(self)
273
- if isinstance(iterable, Expression):
274
- iterable.set_parent(self)
275
-
276
- for stmt in self.body:
277
- if isinstance(stmt, Statement):
278
- stmt.set_parent(self)
279
-
280
- def get_children(self) -> List[IAstNode]:
281
- result: List[IAstNode] = [
282
- cast(IAstNode, self.target),
283
- cast(IAstNode, self.iterable)
284
- ]
285
- result.extend(cast(List[IAstNode], self.body))
286
- return result
287
-
288
- def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
289
- return visitor.visit_forloop(self)
290
-
291
- def get_target(self) -> IExpression:
292
- """Get the loop target."""
293
- return self.target
294
-
295
- def get_iterable(self) -> IExpression:
296
- """Get the iterable expression."""
297
- return self.iterable
298
-
299
- def get_body(self) -> List[IStatement]:
300
- """Get the loop body."""
301
- return self.body
302
-
303
- def add_statement(self, statement: IStatement) -> None:
304
- """Add a statement to the loop body."""
305
- self.body.append(statement)
306
- if isinstance(statement, Statement):
307
- statement.set_parent(self)
308
-
309
- class ReturnStatement(Statement):
310
- """A return statement."""
311
-
312
- _fields = ('value',)
313
-
314
- def __init__(self, value: Optional[IExpression] = None,
315
- location: Optional[SourceLocation] = None):
316
- super().__init__(location)
317
- self.value = value
318
- if isinstance(value, Expression):
319
- value.set_parent(self)
320
-
321
- def get_children(self) -> List[IAstNode]:
322
- return [cast(IAstNode, self.value)] if self.value else []
323
-
324
- def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
325
- return visitor.visit_returnstatement(self)
326
-
327
- def get_value(self) -> Optional[IExpression]:
328
- """Get the return value, if any."""
329
- return self.value
330
-
331
- class BreakStatement(Statement):
332
- """A break statement."""
333
-
334
- _fields = ()
335
-
336
- def get_children(self) -> List[IAstNode]:
337
- return []
338
-
339
- def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
340
- return visitor.visit_breakstatement(self)
341
-
342
- class ContinueStatement(Statement):
343
- """A continue statement."""
344
-
345
- _fields = ()
346
-
347
- def get_children(self) -> List[IAstNode]:
348
- return []
349
-
350
- def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
351
- return visitor.visit_continuestatement(self)
1
+ """Statement nodes for the AST."""
2
+
3
+ from typing import Dict, List, Optional, Union, cast, Any
4
+
5
+ from .interfaces import IAstNode, IExpression, IStatement, IVisitor, T_VisitorResult, IAssignment
6
+ from .core import Statement, Expression
7
+ from .expressions import Identifier
8
+ from ..utils.source_location import SourceLocation
9
+
10
+ class ExpressionStatement(Statement):
11
+ """An expression used as a statement."""
12
+
13
+ _fields = ('expression',)
14
+
15
+ def __init__(self, expression: IExpression, location: Optional[SourceLocation] = None):
16
+ super().__init__(location)
17
+ self.expression = expression
18
+ if isinstance(expression, Expression):
19
+ expression.set_parent(self)
20
+
21
+ def get_children(self) -> List[IAstNode]:
22
+ return [cast(IAstNode, self.expression)]
23
+
24
+ def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
25
+ return visitor.visit_expressionstatement(self)
26
+
27
+ def get_expression(self) -> IExpression:
28
+ """Get the expression."""
29
+ return self.expression
30
+
31
+ class Assignment(Statement, IAssignment):
32
+ """An assignment statement (target = value)."""
33
+
34
+ _fields = ('target', 'value')
35
+
36
+ def __init__(self, target: IExpression, value: IExpression,
37
+ location: Optional[SourceLocation] = None):
38
+ super().__init__(location)
39
+ self.target = target
40
+ self.value = value
41
+ if isinstance(target, Expression):
42
+ target.set_parent(self)
43
+ if isinstance(value, Expression):
44
+ value.set_parent(self)
45
+
46
+ def get_children(self) -> List[IAstNode]:
47
+ return [cast(IAstNode, self.target), cast(IAstNode, self.value)]
48
+
49
+ def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
50
+ return visitor.visit_assignment(self)
51
+
52
+ def get_target(self) -> IExpression:
53
+ """Get the assignment target."""
54
+ return self.target
55
+
56
+ def get_value(self) -> IExpression:
57
+ """Get the assigned value."""
58
+ return self.value
59
+
60
+ class Argument(Statement):
61
+ """A function argument in a definition."""
62
+
63
+ _fields = ('name', 'annotation', 'default')
64
+
65
+ def __init__(self, name: str, annotation: Optional[IExpression] = None,
66
+ default: Optional[IExpression] = None,
67
+ location: Optional[SourceLocation] = None):
68
+ super().__init__(location)
69
+ self.name = name
70
+ self.annotation = annotation
71
+ self.default = default
72
+
73
+ if isinstance(annotation, Expression):
74
+ annotation.set_parent(self)
75
+ if isinstance(default, Expression):
76
+ default.set_parent(self)
77
+
78
+ def get_children(self) -> List[IAstNode]:
79
+ result: List[IAstNode] = []
80
+ if self.annotation:
81
+ result.append(cast(IAstNode, self.annotation))
82
+ if self.default:
83
+ result.append(cast(IAstNode, self.default))
84
+ return result
85
+
86
+ def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
87
+ return visitor.visit_argument(self)
88
+
89
+ def get_name(self) -> str:
90
+ """Get the argument name."""
91
+ return self.name
92
+
93
+ def get_annotation(self) -> Optional[IExpression]:
94
+ """Get the type annotation, if any."""
95
+ return self.annotation
96
+
97
+ def get_default(self) -> Optional[IExpression]:
98
+ """Get the default value, if any."""
99
+ return self.default
100
+
101
+ class FunctionDefinition(Statement):
102
+ """A function definition."""
103
+
104
+ _fields = ('name', 'args', 'body', 'return_annotation')
105
+
106
+ def __init__(self, name: str, args: List[Argument], body: List[IStatement],
107
+ return_annotation: Optional[IExpression] = None,
108
+ location: Optional[SourceLocation] = None):
109
+ super().__init__(location)
110
+ self.name = name
111
+ self.args = args
112
+ self.body = body
113
+ self.return_annotation = return_annotation
114
+
115
+ # Set parent references
116
+ for arg in self.args:
117
+ if isinstance(arg, Statement):
118
+ arg.set_parent(self)
119
+
120
+ for stmt in self.body:
121
+ if isinstance(stmt, Statement):
122
+ stmt.set_parent(self)
123
+
124
+ if isinstance(return_annotation, Expression):
125
+ return_annotation.set_parent(self)
126
+
127
+ def get_children(self) -> List[IAstNode]:
128
+ result: List[IAstNode] = cast(List[IAstNode], self.args)
129
+ result.extend(cast(List[IAstNode], self.body))
130
+ if self.return_annotation:
131
+ result.append(cast(IAstNode, self.return_annotation))
132
+ return result
133
+
134
+ def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
135
+ return visitor.visit_functiondefinition(self)
136
+
137
+ def get_name(self) -> str:
138
+ """Get the function name."""
139
+ return self.name
140
+
141
+ def get_arguments(self) -> List[Argument]:
142
+ """Get the function arguments."""
143
+ return self.args
144
+
145
+ def get_body(self) -> List[IStatement]:
146
+ """Get the function body."""
147
+ return self.body
148
+
149
+ def get_return_annotation(self) -> Optional[IExpression]:
150
+ """Get the return type annotation, if any."""
151
+ return self.return_annotation
152
+
153
+ def add_statement(self, statement: IStatement) -> None:
154
+ """Add a statement to the function body."""
155
+ self.body.append(statement)
156
+ if isinstance(statement, Statement):
157
+ statement.set_parent(self)
158
+
159
+ class IfStatement(Statement):
160
+ """An if statement with optional else branch."""
161
+
162
+ _fields = ('test', 'body', 'orelse')
163
+
164
+ def __init__(self, test: IExpression, body: List[IStatement],
165
+ orelse: Optional[Union[List[IStatement], 'IfStatement']] = None,
166
+ location: Optional[SourceLocation] = None):
167
+ super().__init__(location)
168
+ self.test = test
169
+ self.body = body
170
+ self.orelse = orelse
171
+
172
+ # Set parent references
173
+ if isinstance(test, Expression):
174
+ test.set_parent(self)
175
+
176
+ for stmt in self.body:
177
+ if isinstance(stmt, Statement):
178
+ stmt.set_parent(self)
179
+
180
+ if isinstance(self.orelse, list):
181
+ for stmt in self.orelse:
182
+ if isinstance(stmt, Statement):
183
+ stmt.set_parent(self)
184
+ elif isinstance(self.orelse, Statement):
185
+ self.orelse.set_parent(self)
186
+
187
+ def get_children(self) -> List[IAstNode]:
188
+ result: List[IAstNode] = [cast(IAstNode, self.test)]
189
+ result.extend(cast(List[IAstNode], self.body))
190
+ if isinstance(self.orelse, list):
191
+ result.extend(cast(List[IAstNode], self.orelse))
192
+ elif self.orelse:
193
+ result.append(cast(IAstNode, self.orelse))
194
+ return result
195
+
196
+ def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
197
+ return visitor.visit_ifstatement(self)
198
+
199
+ def get_test(self) -> IExpression:
200
+ """Get the test condition."""
201
+ return self.test
202
+
203
+ def get_body(self) -> List[IStatement]:
204
+ """Get the if body."""
205
+ return self.body
206
+
207
+ def get_else(self) -> Optional[Union[List[IStatement], 'IfStatement']]:
208
+ """Get the else branch, if any."""
209
+ return self.orelse
210
+
211
+ def add_statement(self, statement: IStatement) -> None:
212
+ """Add a statement to the if body."""
213
+ self.body.append(statement)
214
+ if isinstance(statement, Statement):
215
+ statement.set_parent(self)
216
+
217
+ class WhileLoop(Statement):
218
+ """A while loop."""
219
+
220
+ _fields = ('test', 'body')
221
+
222
+ def __init__(self, test: IExpression, body: List[IStatement],
223
+ location: Optional[SourceLocation] = None):
224
+ super().__init__(location)
225
+ self.test = test
226
+ self.body = body
227
+
228
+ # Set parent references
229
+ if isinstance(test, Expression):
230
+ test.set_parent(self)
231
+
232
+ for stmt in self.body:
233
+ if isinstance(stmt, Statement):
234
+ stmt.set_parent(self)
235
+
236
+ def get_children(self) -> List[IAstNode]:
237
+ result: List[IAstNode] = [cast(IAstNode, self.test)]
238
+ result.extend(cast(List[IAstNode], self.body))
239
+ return result
240
+
241
+ def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
242
+ return visitor.visit_whileloop(self)
243
+
244
+ def get_test(self) -> IExpression:
245
+ """Get the test condition."""
246
+ return self.test
247
+
248
+ def get_body(self) -> List[IStatement]:
249
+ """Get the loop body."""
250
+ return self.body
251
+
252
+ def add_statement(self, statement: IStatement) -> None:
253
+ """Add a statement to the loop body."""
254
+ self.body.append(statement)
255
+ if isinstance(statement, Statement):
256
+ statement.set_parent(self)
257
+
258
+ class ForLoop(Statement):
259
+ """A for loop (for target in iterable)."""
260
+
261
+ _fields = ('target', 'iterable', 'body')
262
+
263
+ def __init__(self, target: IExpression, iterable: IExpression,
264
+ body: List[IStatement], location: Optional[SourceLocation] = None):
265
+ super().__init__(location)
266
+ self.target = target
267
+ self.iterable = iterable
268
+ self.body = body
269
+
270
+ # Set parent references
271
+ if isinstance(target, Expression):
272
+ target.set_parent(self)
273
+ if isinstance(iterable, Expression):
274
+ iterable.set_parent(self)
275
+
276
+ for stmt in self.body:
277
+ if isinstance(stmt, Statement):
278
+ stmt.set_parent(self)
279
+
280
+ def get_children(self) -> List[IAstNode]:
281
+ result: List[IAstNode] = [
282
+ cast(IAstNode, self.target),
283
+ cast(IAstNode, self.iterable)
284
+ ]
285
+ result.extend(cast(List[IAstNode], self.body))
286
+ return result
287
+
288
+ def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
289
+ return visitor.visit_forloop(self)
290
+
291
+ def get_target(self) -> IExpression:
292
+ """Get the loop target."""
293
+ return self.target
294
+
295
+ def get_iterable(self) -> IExpression:
296
+ """Get the iterable expression."""
297
+ return self.iterable
298
+
299
+ def get_body(self) -> List[IStatement]:
300
+ """Get the loop body."""
301
+ return self.body
302
+
303
+ def add_statement(self, statement: IStatement) -> None:
304
+ """Add a statement to the loop body."""
305
+ self.body.append(statement)
306
+ if isinstance(statement, Statement):
307
+ statement.set_parent(self)
308
+
309
+ class ReturnStatement(Statement):
310
+ """A return statement."""
311
+
312
+ _fields = ('value',)
313
+
314
+ def __init__(self, value: Optional[IExpression] = None,
315
+ location: Optional[SourceLocation] = None):
316
+ super().__init__(location)
317
+ self.value = value
318
+ if isinstance(value, Expression):
319
+ value.set_parent(self)
320
+
321
+ def get_children(self) -> List[IAstNode]:
322
+ return [cast(IAstNode, self.value)] if self.value else []
323
+
324
+ def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
325
+ return visitor.visit_returnstatement(self)
326
+
327
+ def get_value(self) -> Optional[IExpression]:
328
+ """Get the return value, if any."""
329
+ return self.value
330
+
331
+ class BreakStatement(Statement):
332
+ """A break statement."""
333
+
334
+ _fields = ()
335
+
336
+ def get_children(self) -> List[IAstNode]:
337
+ return []
338
+
339
+ def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
340
+ return visitor.visit_breakstatement(self)
341
+
342
+ class ContinueStatement(Statement):
343
+ """A continue statement."""
344
+
345
+ _fields = ()
346
+
347
+ def get_children(self) -> List[IAstNode]:
348
+ return []
349
+
350
+ def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
351
+ return visitor.visit_continuestatement(self)