vex-ast 0.2.5__py3-none-any.whl → 0.2.7__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.
- vex_ast/README.md +101 -51
- vex_ast/READMEAPI.md +133 -318
- vex_ast/__init__.py +81 -81
- vex_ast/ast/README.md +87 -87
- vex_ast/ast/__init__.py +74 -74
- vex_ast/ast/core.py +71 -71
- vex_ast/ast/expressions.py +276 -276
- vex_ast/ast/interfaces.py +208 -208
- vex_ast/ast/literals.py +80 -80
- vex_ast/ast/navigator.py +241 -225
- vex_ast/ast/operators.py +135 -135
- vex_ast/ast/statements.py +351 -351
- vex_ast/ast/validators.py +121 -121
- vex_ast/ast/vex_nodes.py +279 -279
- vex_ast/parser/README.md +47 -47
- vex_ast/parser/__init__.py +26 -26
- vex_ast/parser/factory.py +190 -190
- vex_ast/parser/interfaces.py +34 -34
- vex_ast/parser/python_parser.py +831 -831
- vex_ast/registry/README.md +107 -29
- vex_ast/registry/__init__.py +51 -51
- vex_ast/registry/api.py +190 -155
- vex_ast/registry/categories.py +179 -136
- vex_ast/registry/functions/__init__.py +10 -10
- vex_ast/registry/functions/constructors.py +71 -35
- vex_ast/registry/functions/display.py +146 -146
- vex_ast/registry/functions/drivetrain.py +163 -163
- vex_ast/registry/functions/initialize.py +31 -31
- vex_ast/registry/functions/motor.py +140 -140
- vex_ast/registry/functions/sensors.py +194 -194
- vex_ast/registry/functions/timing.py +103 -103
- vex_ast/registry/language_map.py +77 -77
- vex_ast/registry/registry.py +164 -153
- vex_ast/registry/signature.py +269 -191
- vex_ast/registry/simulation_behavior.py +8 -8
- vex_ast/registry/validation.py +43 -43
- vex_ast/serialization/__init__.py +37 -37
- vex_ast/serialization/json_deserializer.py +284 -284
- vex_ast/serialization/json_serializer.py +148 -148
- vex_ast/serialization/schema.py +492 -492
- vex_ast/types/README.md +78 -26
- vex_ast/types/__init__.py +140 -140
- vex_ast/types/base.py +83 -83
- vex_ast/types/enums.py +122 -122
- vex_ast/types/objects.py +64 -64
- vex_ast/types/primitives.py +68 -68
- vex_ast/types/type_checker.py +31 -31
- vex_ast/utils/README.md +39 -39
- vex_ast/utils/__init__.py +37 -37
- vex_ast/utils/errors.py +112 -112
- vex_ast/utils/source_location.py +38 -38
- vex_ast/utils/type_definitions.py +8 -8
- vex_ast/visitors/README.md +49 -49
- vex_ast/visitors/__init__.py +27 -27
- vex_ast/visitors/analyzer.py +102 -102
- vex_ast/visitors/base.py +133 -133
- vex_ast/visitors/printer.py +196 -196
- {vex_ast-0.2.5.dist-info → vex_ast-0.2.7.dist-info}/METADATA +206 -174
- vex_ast-0.2.7.dist-info/RECORD +64 -0
- vex_ast-0.2.5.dist-info/RECORD +0 -64
- {vex_ast-0.2.5.dist-info → vex_ast-0.2.7.dist-info}/WHEEL +0 -0
- {vex_ast-0.2.5.dist-info → vex_ast-0.2.7.dist-info}/licenses/LICENSE +0 -0
- {vex_ast-0.2.5.dist-info → vex_ast-0.2.7.dist-info}/top_level.txt +0 -0
vex_ast/ast/expressions.py
CHANGED
@@ -1,276 +1,276 @@
|
|
1
|
-
"""Expression nodes for the AST."""
|
2
|
-
|
3
|
-
from typing import Dict, List, Optional, Union, cast, Any
|
4
|
-
|
5
|
-
from .interfaces import IAstNode, IExpression, IVisitor, T_VisitorResult, IIdentifier, IFunctionCall, IConditionalExpression
|
6
|
-
from .core import Expression
|
7
|
-
from .operators import Operator
|
8
|
-
from ..utils.source_location import SourceLocation
|
9
|
-
|
10
|
-
class Identifier(Expression, IIdentifier):
|
11
|
-
"""An identifier (variable name, function name, etc.)."""
|
12
|
-
|
13
|
-
_fields = ('name',)
|
14
|
-
|
15
|
-
def __init__(self, name: str, location: Optional[SourceLocation] = None):
|
16
|
-
super().__init__(location)
|
17
|
-
self.name = name
|
18
|
-
|
19
|
-
def get_children(self) -> List[IAstNode]:
|
20
|
-
"""Identifiers have no children."""
|
21
|
-
return []
|
22
|
-
|
23
|
-
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
24
|
-
return visitor.visit_identifier(self)
|
25
|
-
|
26
|
-
def get_name(self) -> str:
|
27
|
-
"""Get the identifier name."""
|
28
|
-
return self.name
|
29
|
-
|
30
|
-
class VariableReference(Expression):
|
31
|
-
"""A reference to a variable."""
|
32
|
-
|
33
|
-
_fields = ('identifier',)
|
34
|
-
|
35
|
-
def __init__(self, identifier: Identifier, location: Optional[SourceLocation] = None):
|
36
|
-
super().__init__(location)
|
37
|
-
self.identifier = identifier
|
38
|
-
if isinstance(identifier, Expression):
|
39
|
-
identifier.set_parent(self)
|
40
|
-
|
41
|
-
@property
|
42
|
-
def name(self) -> str:
|
43
|
-
"""Convenience property to get the variable name."""
|
44
|
-
return self.identifier.name
|
45
|
-
|
46
|
-
def get_children(self) -> List[IAstNode]:
|
47
|
-
"""Get child nodes."""
|
48
|
-
return [self.identifier]
|
49
|
-
|
50
|
-
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
51
|
-
return visitor.visit_variablereference(self)
|
52
|
-
|
53
|
-
def get_identifier(self) -> IIdentifier:
|
54
|
-
"""Get the identifier being referenced."""
|
55
|
-
return self.identifier
|
56
|
-
|
57
|
-
class AttributeAccess(Expression):
|
58
|
-
"""An attribute access expression (e.g., object.attribute)."""
|
59
|
-
|
60
|
-
_fields = ('object', 'attribute')
|
61
|
-
|
62
|
-
def __init__(self, object_expr: IExpression, attribute: str,
|
63
|
-
location: Optional[SourceLocation] = None):
|
64
|
-
super().__init__(location)
|
65
|
-
self.object = object_expr
|
66
|
-
self.attribute = attribute
|
67
|
-
if isinstance(object_expr, Expression):
|
68
|
-
object_expr.set_parent(self)
|
69
|
-
|
70
|
-
def get_children(self) -> List[IAstNode]:
|
71
|
-
"""Get child nodes."""
|
72
|
-
return [cast(IAstNode, self.object)]
|
73
|
-
|
74
|
-
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
75
|
-
return visitor.visit_attributeaccess(self)
|
76
|
-
|
77
|
-
def get_object(self) -> IExpression:
|
78
|
-
"""Get the object expression."""
|
79
|
-
return self.object
|
80
|
-
|
81
|
-
def get_attribute_name(self) -> str:
|
82
|
-
"""Get the attribute name."""
|
83
|
-
return self.attribute
|
84
|
-
|
85
|
-
class BinaryOperation(Expression):
|
86
|
-
"""A binary operation (e.g., a + b)."""
|
87
|
-
|
88
|
-
_fields = ('left', 'op', 'right')
|
89
|
-
|
90
|
-
def __init__(self, left: IExpression, op: Operator, right: IExpression,
|
91
|
-
location: Optional[SourceLocation] = None):
|
92
|
-
super().__init__(location)
|
93
|
-
self.left = left
|
94
|
-
self.op = op
|
95
|
-
self.right = right
|
96
|
-
if isinstance(left, Expression):
|
97
|
-
left.set_parent(self)
|
98
|
-
if isinstance(right, Expression):
|
99
|
-
right.set_parent(self)
|
100
|
-
|
101
|
-
def get_children(self) -> List[IAstNode]:
|
102
|
-
"""Get child nodes."""
|
103
|
-
return [cast(IAstNode, self.left), cast(IAstNode, self.right)]
|
104
|
-
|
105
|
-
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
106
|
-
return visitor.visit_binaryoperation(self)
|
107
|
-
|
108
|
-
def get_left(self) -> IExpression:
|
109
|
-
"""Get the left operand."""
|
110
|
-
return self.left
|
111
|
-
|
112
|
-
def get_right(self) -> IExpression:
|
113
|
-
"""Get the right operand."""
|
114
|
-
return self.right
|
115
|
-
|
116
|
-
def get_operator(self) -> Operator:
|
117
|
-
"""Get the operator."""
|
118
|
-
return self.op
|
119
|
-
|
120
|
-
class UnaryOperation(Expression):
|
121
|
-
"""A unary operation (e.g., -a, not b)."""
|
122
|
-
|
123
|
-
_fields = ('op', 'operand')
|
124
|
-
|
125
|
-
def __init__(self, op: Operator, operand: IExpression,
|
126
|
-
location: Optional[SourceLocation] = None):
|
127
|
-
super().__init__(location)
|
128
|
-
self.op = op
|
129
|
-
self.operand = operand
|
130
|
-
if isinstance(operand, Expression):
|
131
|
-
operand.set_parent(self)
|
132
|
-
|
133
|
-
def get_children(self) -> List[IAstNode]:
|
134
|
-
"""Get child nodes."""
|
135
|
-
return [cast(IAstNode, self.operand)]
|
136
|
-
|
137
|
-
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
138
|
-
return visitor.visit_unaryoperation(self)
|
139
|
-
|
140
|
-
def get_operand(self) -> IExpression:
|
141
|
-
"""Get the operand."""
|
142
|
-
return self.operand
|
143
|
-
|
144
|
-
def get_operator(self) -> Operator:
|
145
|
-
"""Get the operator."""
|
146
|
-
return self.op
|
147
|
-
|
148
|
-
class KeywordArgument(Expression):
|
149
|
-
"""A keyword argument in a function call (name=value)."""
|
150
|
-
|
151
|
-
_fields = ('name', 'value')
|
152
|
-
|
153
|
-
def __init__(self, name: str, value: IExpression,
|
154
|
-
location: Optional[SourceLocation] = None):
|
155
|
-
super().__init__(location)
|
156
|
-
self.name = name
|
157
|
-
self.value = value
|
158
|
-
if isinstance(value, Expression):
|
159
|
-
value.set_parent(self)
|
160
|
-
|
161
|
-
def get_children(self) -> List[IAstNode]:
|
162
|
-
"""Get child nodes."""
|
163
|
-
return [cast(IAstNode, self.value)]
|
164
|
-
|
165
|
-
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
166
|
-
return visitor.visit_keywordargument(self)
|
167
|
-
|
168
|
-
def get_name(self) -> str:
|
169
|
-
"""Get the keyword name."""
|
170
|
-
return self.name
|
171
|
-
|
172
|
-
def get_value(self) -> IExpression:
|
173
|
-
"""Get the keyword value."""
|
174
|
-
return self.value
|
175
|
-
|
176
|
-
class ConditionalExpression(Expression, IConditionalExpression):
|
177
|
-
"""A conditional expression (ternary operator, e.g., a if condition else b)."""
|
178
|
-
|
179
|
-
_fields = ('condition', 'true_expr', 'false_expr')
|
180
|
-
|
181
|
-
def __init__(self, condition: IExpression, true_expr: IExpression, false_expr: IExpression,
|
182
|
-
location: Optional[SourceLocation] = None):
|
183
|
-
super().__init__(location)
|
184
|
-
self.condition = condition
|
185
|
-
self.true_expr = true_expr
|
186
|
-
self.false_expr = false_expr
|
187
|
-
|
188
|
-
# Set parent references
|
189
|
-
if isinstance(condition, Expression):
|
190
|
-
condition.set_parent(self)
|
191
|
-
if isinstance(true_expr, Expression):
|
192
|
-
true_expr.set_parent(self)
|
193
|
-
if isinstance(false_expr, Expression):
|
194
|
-
false_expr.set_parent(self)
|
195
|
-
|
196
|
-
def get_children(self) -> List[IAstNode]:
|
197
|
-
"""Get child nodes."""
|
198
|
-
return [
|
199
|
-
cast(IAstNode, self.condition),
|
200
|
-
cast(IAstNode, self.true_expr),
|
201
|
-
cast(IAstNode, self.false_expr)
|
202
|
-
]
|
203
|
-
|
204
|
-
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
205
|
-
return visitor.visit_conditionalexpression(self)
|
206
|
-
|
207
|
-
def get_condition(self) -> IExpression:
|
208
|
-
"""Get the condition expression."""
|
209
|
-
return self.condition
|
210
|
-
|
211
|
-
def get_true_expression(self) -> IExpression:
|
212
|
-
"""Get the expression to evaluate if condition is true."""
|
213
|
-
return self.true_expr
|
214
|
-
|
215
|
-
def get_false_expression(self) -> IExpression:
|
216
|
-
"""Get the expression to evaluate if condition is false."""
|
217
|
-
return self.false_expr
|
218
|
-
|
219
|
-
class FunctionCall(Expression, IFunctionCall):
|
220
|
-
"""A function call."""
|
221
|
-
|
222
|
-
_fields = ('function', 'args', 'keywords')
|
223
|
-
|
224
|
-
def __init__(self, function: IExpression, args: List[IExpression],
|
225
|
-
keywords: List[KeywordArgument] = None,
|
226
|
-
location: Optional[SourceLocation] = None):
|
227
|
-
super().__init__(location)
|
228
|
-
self.function = function
|
229
|
-
self.args = args or []
|
230
|
-
self.keywords = keywords or []
|
231
|
-
|
232
|
-
# Set parent references
|
233
|
-
if isinstance(function, Expression):
|
234
|
-
function.set_parent(self)
|
235
|
-
|
236
|
-
for arg in self.args:
|
237
|
-
if isinstance(arg, Expression):
|
238
|
-
arg.set_parent(self)
|
239
|
-
|
240
|
-
for kw in self.keywords:
|
241
|
-
if isinstance(kw, Expression):
|
242
|
-
kw.set_parent(self)
|
243
|
-
|
244
|
-
def get_children(self) -> List[IAstNode]:
|
245
|
-
"""Get child nodes."""
|
246
|
-
result: List[IAstNode] = [cast(IAstNode, self.function)]
|
247
|
-
result.extend(cast(List[IAstNode], self.args))
|
248
|
-
result.extend(cast(List[IAstNode], self.keywords))
|
249
|
-
return result
|
250
|
-
|
251
|
-
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
252
|
-
return visitor.visit_functioncall(self)
|
253
|
-
|
254
|
-
def get_function_expr(self) -> IExpression:
|
255
|
-
"""Get the function expression."""
|
256
|
-
return self.function
|
257
|
-
|
258
|
-
def get_arguments(self) -> List[IExpression]:
|
259
|
-
"""Get the positional arguments."""
|
260
|
-
return self.args
|
261
|
-
|
262
|
-
def get_keyword_arguments(self) -> Dict[str, IExpression]:
|
263
|
-
"""Get the keyword arguments as a dictionary."""
|
264
|
-
return {kw.name: kw.value for kw in self.keywords}
|
265
|
-
|
266
|
-
def add_argument(self, arg: IExpression) -> None:
|
267
|
-
"""Add a positional argument."""
|
268
|
-
self.args.append(arg)
|
269
|
-
if isinstance(arg, Expression):
|
270
|
-
arg.set_parent(self)
|
271
|
-
|
272
|
-
def add_keyword_argument(self, name: str, value: IExpression) -> None:
|
273
|
-
"""Add a keyword argument."""
|
274
|
-
kw = KeywordArgument(name, value)
|
275
|
-
self.keywords.append(kw)
|
276
|
-
kw.set_parent(self)
|
1
|
+
"""Expression nodes for the AST."""
|
2
|
+
|
3
|
+
from typing import Dict, List, Optional, Union, cast, Any
|
4
|
+
|
5
|
+
from .interfaces import IAstNode, IExpression, IVisitor, T_VisitorResult, IIdentifier, IFunctionCall, IConditionalExpression
|
6
|
+
from .core import Expression
|
7
|
+
from .operators import Operator
|
8
|
+
from ..utils.source_location import SourceLocation
|
9
|
+
|
10
|
+
class Identifier(Expression, IIdentifier):
|
11
|
+
"""An identifier (variable name, function name, etc.)."""
|
12
|
+
|
13
|
+
_fields = ('name',)
|
14
|
+
|
15
|
+
def __init__(self, name: str, location: Optional[SourceLocation] = None):
|
16
|
+
super().__init__(location)
|
17
|
+
self.name = name
|
18
|
+
|
19
|
+
def get_children(self) -> List[IAstNode]:
|
20
|
+
"""Identifiers have no children."""
|
21
|
+
return []
|
22
|
+
|
23
|
+
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
24
|
+
return visitor.visit_identifier(self)
|
25
|
+
|
26
|
+
def get_name(self) -> str:
|
27
|
+
"""Get the identifier name."""
|
28
|
+
return self.name
|
29
|
+
|
30
|
+
class VariableReference(Expression):
|
31
|
+
"""A reference to a variable."""
|
32
|
+
|
33
|
+
_fields = ('identifier',)
|
34
|
+
|
35
|
+
def __init__(self, identifier: Identifier, location: Optional[SourceLocation] = None):
|
36
|
+
super().__init__(location)
|
37
|
+
self.identifier = identifier
|
38
|
+
if isinstance(identifier, Expression):
|
39
|
+
identifier.set_parent(self)
|
40
|
+
|
41
|
+
@property
|
42
|
+
def name(self) -> str:
|
43
|
+
"""Convenience property to get the variable name."""
|
44
|
+
return self.identifier.name
|
45
|
+
|
46
|
+
def get_children(self) -> List[IAstNode]:
|
47
|
+
"""Get child nodes."""
|
48
|
+
return [self.identifier]
|
49
|
+
|
50
|
+
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
51
|
+
return visitor.visit_variablereference(self)
|
52
|
+
|
53
|
+
def get_identifier(self) -> IIdentifier:
|
54
|
+
"""Get the identifier being referenced."""
|
55
|
+
return self.identifier
|
56
|
+
|
57
|
+
class AttributeAccess(Expression):
|
58
|
+
"""An attribute access expression (e.g., object.attribute)."""
|
59
|
+
|
60
|
+
_fields = ('object', 'attribute')
|
61
|
+
|
62
|
+
def __init__(self, object_expr: IExpression, attribute: str,
|
63
|
+
location: Optional[SourceLocation] = None):
|
64
|
+
super().__init__(location)
|
65
|
+
self.object = object_expr
|
66
|
+
self.attribute = attribute
|
67
|
+
if isinstance(object_expr, Expression):
|
68
|
+
object_expr.set_parent(self)
|
69
|
+
|
70
|
+
def get_children(self) -> List[IAstNode]:
|
71
|
+
"""Get child nodes."""
|
72
|
+
return [cast(IAstNode, self.object)]
|
73
|
+
|
74
|
+
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
75
|
+
return visitor.visit_attributeaccess(self)
|
76
|
+
|
77
|
+
def get_object(self) -> IExpression:
|
78
|
+
"""Get the object expression."""
|
79
|
+
return self.object
|
80
|
+
|
81
|
+
def get_attribute_name(self) -> str:
|
82
|
+
"""Get the attribute name."""
|
83
|
+
return self.attribute
|
84
|
+
|
85
|
+
class BinaryOperation(Expression):
|
86
|
+
"""A binary operation (e.g., a + b)."""
|
87
|
+
|
88
|
+
_fields = ('left', 'op', 'right')
|
89
|
+
|
90
|
+
def __init__(self, left: IExpression, op: Operator, right: IExpression,
|
91
|
+
location: Optional[SourceLocation] = None):
|
92
|
+
super().__init__(location)
|
93
|
+
self.left = left
|
94
|
+
self.op = op
|
95
|
+
self.right = right
|
96
|
+
if isinstance(left, Expression):
|
97
|
+
left.set_parent(self)
|
98
|
+
if isinstance(right, Expression):
|
99
|
+
right.set_parent(self)
|
100
|
+
|
101
|
+
def get_children(self) -> List[IAstNode]:
|
102
|
+
"""Get child nodes."""
|
103
|
+
return [cast(IAstNode, self.left), cast(IAstNode, self.right)]
|
104
|
+
|
105
|
+
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
106
|
+
return visitor.visit_binaryoperation(self)
|
107
|
+
|
108
|
+
def get_left(self) -> IExpression:
|
109
|
+
"""Get the left operand."""
|
110
|
+
return self.left
|
111
|
+
|
112
|
+
def get_right(self) -> IExpression:
|
113
|
+
"""Get the right operand."""
|
114
|
+
return self.right
|
115
|
+
|
116
|
+
def get_operator(self) -> Operator:
|
117
|
+
"""Get the operator."""
|
118
|
+
return self.op
|
119
|
+
|
120
|
+
class UnaryOperation(Expression):
|
121
|
+
"""A unary operation (e.g., -a, not b)."""
|
122
|
+
|
123
|
+
_fields = ('op', 'operand')
|
124
|
+
|
125
|
+
def __init__(self, op: Operator, operand: IExpression,
|
126
|
+
location: Optional[SourceLocation] = None):
|
127
|
+
super().__init__(location)
|
128
|
+
self.op = op
|
129
|
+
self.operand = operand
|
130
|
+
if isinstance(operand, Expression):
|
131
|
+
operand.set_parent(self)
|
132
|
+
|
133
|
+
def get_children(self) -> List[IAstNode]:
|
134
|
+
"""Get child nodes."""
|
135
|
+
return [cast(IAstNode, self.operand)]
|
136
|
+
|
137
|
+
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
138
|
+
return visitor.visit_unaryoperation(self)
|
139
|
+
|
140
|
+
def get_operand(self) -> IExpression:
|
141
|
+
"""Get the operand."""
|
142
|
+
return self.operand
|
143
|
+
|
144
|
+
def get_operator(self) -> Operator:
|
145
|
+
"""Get the operator."""
|
146
|
+
return self.op
|
147
|
+
|
148
|
+
class KeywordArgument(Expression):
|
149
|
+
"""A keyword argument in a function call (name=value)."""
|
150
|
+
|
151
|
+
_fields = ('name', 'value')
|
152
|
+
|
153
|
+
def __init__(self, name: str, value: IExpression,
|
154
|
+
location: Optional[SourceLocation] = None):
|
155
|
+
super().__init__(location)
|
156
|
+
self.name = name
|
157
|
+
self.value = value
|
158
|
+
if isinstance(value, Expression):
|
159
|
+
value.set_parent(self)
|
160
|
+
|
161
|
+
def get_children(self) -> List[IAstNode]:
|
162
|
+
"""Get child nodes."""
|
163
|
+
return [cast(IAstNode, self.value)]
|
164
|
+
|
165
|
+
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
166
|
+
return visitor.visit_keywordargument(self)
|
167
|
+
|
168
|
+
def get_name(self) -> str:
|
169
|
+
"""Get the keyword name."""
|
170
|
+
return self.name
|
171
|
+
|
172
|
+
def get_value(self) -> IExpression:
|
173
|
+
"""Get the keyword value."""
|
174
|
+
return self.value
|
175
|
+
|
176
|
+
class ConditionalExpression(Expression, IConditionalExpression):
|
177
|
+
"""A conditional expression (ternary operator, e.g., a if condition else b)."""
|
178
|
+
|
179
|
+
_fields = ('condition', 'true_expr', 'false_expr')
|
180
|
+
|
181
|
+
def __init__(self, condition: IExpression, true_expr: IExpression, false_expr: IExpression,
|
182
|
+
location: Optional[SourceLocation] = None):
|
183
|
+
super().__init__(location)
|
184
|
+
self.condition = condition
|
185
|
+
self.true_expr = true_expr
|
186
|
+
self.false_expr = false_expr
|
187
|
+
|
188
|
+
# Set parent references
|
189
|
+
if isinstance(condition, Expression):
|
190
|
+
condition.set_parent(self)
|
191
|
+
if isinstance(true_expr, Expression):
|
192
|
+
true_expr.set_parent(self)
|
193
|
+
if isinstance(false_expr, Expression):
|
194
|
+
false_expr.set_parent(self)
|
195
|
+
|
196
|
+
def get_children(self) -> List[IAstNode]:
|
197
|
+
"""Get child nodes."""
|
198
|
+
return [
|
199
|
+
cast(IAstNode, self.condition),
|
200
|
+
cast(IAstNode, self.true_expr),
|
201
|
+
cast(IAstNode, self.false_expr)
|
202
|
+
]
|
203
|
+
|
204
|
+
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
205
|
+
return visitor.visit_conditionalexpression(self)
|
206
|
+
|
207
|
+
def get_condition(self) -> IExpression:
|
208
|
+
"""Get the condition expression."""
|
209
|
+
return self.condition
|
210
|
+
|
211
|
+
def get_true_expression(self) -> IExpression:
|
212
|
+
"""Get the expression to evaluate if condition is true."""
|
213
|
+
return self.true_expr
|
214
|
+
|
215
|
+
def get_false_expression(self) -> IExpression:
|
216
|
+
"""Get the expression to evaluate if condition is false."""
|
217
|
+
return self.false_expr
|
218
|
+
|
219
|
+
class FunctionCall(Expression, IFunctionCall):
|
220
|
+
"""A function call."""
|
221
|
+
|
222
|
+
_fields = ('function', 'args', 'keywords')
|
223
|
+
|
224
|
+
def __init__(self, function: IExpression, args: List[IExpression],
|
225
|
+
keywords: List[KeywordArgument] = None,
|
226
|
+
location: Optional[SourceLocation] = None):
|
227
|
+
super().__init__(location)
|
228
|
+
self.function = function
|
229
|
+
self.args = args or []
|
230
|
+
self.keywords = keywords or []
|
231
|
+
|
232
|
+
# Set parent references
|
233
|
+
if isinstance(function, Expression):
|
234
|
+
function.set_parent(self)
|
235
|
+
|
236
|
+
for arg in self.args:
|
237
|
+
if isinstance(arg, Expression):
|
238
|
+
arg.set_parent(self)
|
239
|
+
|
240
|
+
for kw in self.keywords:
|
241
|
+
if isinstance(kw, Expression):
|
242
|
+
kw.set_parent(self)
|
243
|
+
|
244
|
+
def get_children(self) -> List[IAstNode]:
|
245
|
+
"""Get child nodes."""
|
246
|
+
result: List[IAstNode] = [cast(IAstNode, self.function)]
|
247
|
+
result.extend(cast(List[IAstNode], self.args))
|
248
|
+
result.extend(cast(List[IAstNode], self.keywords))
|
249
|
+
return result
|
250
|
+
|
251
|
+
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
252
|
+
return visitor.visit_functioncall(self)
|
253
|
+
|
254
|
+
def get_function_expr(self) -> IExpression:
|
255
|
+
"""Get the function expression."""
|
256
|
+
return self.function
|
257
|
+
|
258
|
+
def get_arguments(self) -> List[IExpression]:
|
259
|
+
"""Get the positional arguments."""
|
260
|
+
return self.args
|
261
|
+
|
262
|
+
def get_keyword_arguments(self) -> Dict[str, IExpression]:
|
263
|
+
"""Get the keyword arguments as a dictionary."""
|
264
|
+
return {kw.name: kw.value for kw in self.keywords}
|
265
|
+
|
266
|
+
def add_argument(self, arg: IExpression) -> None:
|
267
|
+
"""Add a positional argument."""
|
268
|
+
self.args.append(arg)
|
269
|
+
if isinstance(arg, Expression):
|
270
|
+
arg.set_parent(self)
|
271
|
+
|
272
|
+
def add_keyword_argument(self, name: str, value: IExpression) -> None:
|
273
|
+
"""Add a keyword argument."""
|
274
|
+
kw = KeywordArgument(name, value)
|
275
|
+
self.keywords.append(kw)
|
276
|
+
kw.set_parent(self)
|