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/interfaces.py
CHANGED
@@ -1,208 +1,208 @@
|
|
1
|
-
"""Fundamental interfaces and protocols for the AST."""
|
2
|
-
|
3
|
-
from abc import ABC, abstractmethod
|
4
|
-
from typing import Any, Iterable, List, Optional, Protocol, TypeVar, Generic, runtime_checkable, Dict, Union, Tuple
|
5
|
-
|
6
|
-
from ..utils.source_location import SourceLocation
|
7
|
-
|
8
|
-
# Visitor pattern type variable
|
9
|
-
T_VisitorResult = TypeVar('T_VisitorResult')
|
10
|
-
|
11
|
-
class IVisitor(Protocol, Generic[T_VisitorResult]):
|
12
|
-
"""Protocol for AST visitors."""
|
13
|
-
|
14
|
-
def visit(self, node: 'IAstNode') -> T_VisitorResult:
|
15
|
-
"""Visit an AST node."""
|
16
|
-
...
|
17
|
-
|
18
|
-
@runtime_checkable
|
19
|
-
class IAstNode(Protocol):
|
20
|
-
"""Protocol defining the minimum interface for an AST node."""
|
21
|
-
|
22
|
-
location: Optional[SourceLocation]
|
23
|
-
|
24
|
-
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
25
|
-
"""Accept a visitor (Visitor Pattern)."""
|
26
|
-
...
|
27
|
-
|
28
|
-
def get_children(self) -> Iterable['IAstNode']:
|
29
|
-
"""Get child nodes of this node."""
|
30
|
-
...
|
31
|
-
|
32
|
-
def get_child_by_name(self, name: str) -> Optional['IAstNode']:
|
33
|
-
"""Get a child node by its field name."""
|
34
|
-
...
|
35
|
-
|
36
|
-
def get_child_names(self) -> List[str]:
|
37
|
-
"""Get the names of all child fields."""
|
38
|
-
...
|
39
|
-
|
40
|
-
def get_parent(self) -> Optional['IAstNode']:
|
41
|
-
"""Get the parent node, if available."""
|
42
|
-
...
|
43
|
-
|
44
|
-
def get_attributes(self) -> Dict[str, Any]:
|
45
|
-
"""Get all attributes of this node as a dictionary."""
|
46
|
-
...
|
47
|
-
|
48
|
-
def to_dict(self) -> Dict[str, Any]:
|
49
|
-
"""
|
50
|
-
Convert the node to a dictionary representation.
|
51
|
-
|
52
|
-
This is an optional method for serialization support.
|
53
|
-
|
54
|
-
Returns:
|
55
|
-
A dictionary representation of the node
|
56
|
-
"""
|
57
|
-
...
|
58
|
-
|
59
|
-
@runtime_checkable
|
60
|
-
class IExpression(IAstNode, Protocol):
|
61
|
-
"""Protocol for expression nodes."""
|
62
|
-
pass
|
63
|
-
|
64
|
-
@runtime_checkable
|
65
|
-
class IStatement(IAstNode, Protocol):
|
66
|
-
"""Protocol for statement nodes."""
|
67
|
-
pass
|
68
|
-
|
69
|
-
@runtime_checkable
|
70
|
-
class ILiteral(IExpression, Protocol):
|
71
|
-
"""Protocol for literal value nodes."""
|
72
|
-
value: Any
|
73
|
-
|
74
|
-
def get_value(self) -> Any:
|
75
|
-
"""Get the literal value."""
|
76
|
-
...
|
77
|
-
|
78
|
-
@runtime_checkable
|
79
|
-
class IIdentifier(IExpression, Protocol):
|
80
|
-
"""Protocol for identifier nodes."""
|
81
|
-
name: str
|
82
|
-
|
83
|
-
def get_name(self) -> str:
|
84
|
-
"""Get the identifier name."""
|
85
|
-
...
|
86
|
-
|
87
|
-
@runtime_checkable
|
88
|
-
class IConditionalExpression(IExpression, Protocol):
|
89
|
-
"""Protocol for conditional expression (ternary operator) nodes."""
|
90
|
-
|
91
|
-
def get_condition(self) -> IExpression:
|
92
|
-
"""Get the condition expression."""
|
93
|
-
...
|
94
|
-
|
95
|
-
def get_true_expression(self) -> IExpression:
|
96
|
-
"""Get the expression to evaluate if condition is true."""
|
97
|
-
...
|
98
|
-
|
99
|
-
def get_false_expression(self) -> IExpression:
|
100
|
-
"""Get the expression to evaluate if condition is false."""
|
101
|
-
...
|
102
|
-
|
103
|
-
@runtime_checkable
|
104
|
-
class IFunctionCall(IExpression, Protocol):
|
105
|
-
"""Protocol for function call nodes."""
|
106
|
-
|
107
|
-
def get_function_expr(self) -> IExpression:
|
108
|
-
"""Get the function expression."""
|
109
|
-
...
|
110
|
-
|
111
|
-
def get_arguments(self) -> List[IExpression]:
|
112
|
-
"""Get the positional arguments."""
|
113
|
-
...
|
114
|
-
|
115
|
-
def get_keyword_arguments(self) -> Dict[str, IExpression]:
|
116
|
-
"""Get the keyword arguments as a dictionary."""
|
117
|
-
...
|
118
|
-
|
119
|
-
@runtime_checkable
|
120
|
-
class IAssignment(IStatement, Protocol):
|
121
|
-
"""Protocol for assignment nodes."""
|
122
|
-
|
123
|
-
def get_target(self) -> IExpression:
|
124
|
-
"""Get the assignment target."""
|
125
|
-
...
|
126
|
-
|
127
|
-
def get_value(self) -> IExpression:
|
128
|
-
"""Get the assigned value."""
|
129
|
-
...
|
130
|
-
|
131
|
-
class AstNode(ABC):
|
132
|
-
"""Abstract base implementation of the IAstNode protocol."""
|
133
|
-
|
134
|
-
def __init__(self, location: Optional[SourceLocation] = None):
|
135
|
-
self.location = location
|
136
|
-
self._parent: Optional[IAstNode] = None
|
137
|
-
|
138
|
-
@abstractmethod
|
139
|
-
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
140
|
-
"""Accept a visitor (Visitor Pattern)."""
|
141
|
-
pass
|
142
|
-
|
143
|
-
@abstractmethod
|
144
|
-
def get_children(self) -> List[IAstNode]:
|
145
|
-
"""Get child nodes of this node."""
|
146
|
-
pass
|
147
|
-
|
148
|
-
def get_child_by_name(self, name: str) -> Optional[IAstNode]:
|
149
|
-
"""Get a child node by its field name."""
|
150
|
-
if not hasattr(self, '_fields') or name not in getattr(self, '_fields'):
|
151
|
-
return None
|
152
|
-
|
153
|
-
value = getattr(self, name, None)
|
154
|
-
if isinstance(value, IAstNode):
|
155
|
-
return value
|
156
|
-
elif isinstance(value, list) and value and isinstance(value[0], IAstNode):
|
157
|
-
return value[0] # Return first item if it's a list of nodes
|
158
|
-
|
159
|
-
return None
|
160
|
-
|
161
|
-
def get_child_names(self) -> List[str]:
|
162
|
-
"""Get the names of all child fields."""
|
163
|
-
if not hasattr(self, '_fields'):
|
164
|
-
return []
|
165
|
-
return list(getattr(self, '_fields'))
|
166
|
-
|
167
|
-
def get_parent(self) -> Optional[IAstNode]:
|
168
|
-
"""Get the parent node, if available."""
|
169
|
-
return getattr(self, '_parent', None)
|
170
|
-
|
171
|
-
def set_parent(self, parent: IAstNode) -> None:
|
172
|
-
"""Set the parent node reference."""
|
173
|
-
self._parent = parent
|
174
|
-
|
175
|
-
def get_attributes(self) -> Dict[str, Any]:
|
176
|
-
"""Get all attributes of this node as a dictionary."""
|
177
|
-
result = {}
|
178
|
-
if hasattr(self, '_fields'):
|
179
|
-
for field in getattr(self, '_fields'):
|
180
|
-
result[field] = getattr(self, field, None)
|
181
|
-
return result
|
182
|
-
|
183
|
-
def __eq__(self, other: Any) -> bool:
|
184
|
-
"""Compare nodes for equality."""
|
185
|
-
if not isinstance(other, self.__class__):
|
186
|
-
return NotImplemented
|
187
|
-
|
188
|
-
# Compare all attributes defined in _fields
|
189
|
-
if hasattr(self, '_fields'):
|
190
|
-
for field in getattr(self, '_fields'):
|
191
|
-
if getattr(self, field, None) != getattr(other, field, None):
|
192
|
-
return False
|
193
|
-
|
194
|
-
# Compare location
|
195
|
-
return self.location == other.location
|
196
|
-
|
197
|
-
def to_dict(self) -> Dict[str, Any]:
|
198
|
-
"""
|
199
|
-
Convert the node to a dictionary representation.
|
200
|
-
|
201
|
-
This implementation uses the serialization visitor to create a
|
202
|
-
dictionary representation of the node.
|
203
|
-
|
204
|
-
Returns:
|
205
|
-
A dictionary representation of the node
|
206
|
-
"""
|
207
|
-
from ..serialization.json_serializer import serialize_ast_to_dict
|
208
|
-
return serialize_ast_to_dict(self)
|
1
|
+
"""Fundamental interfaces and protocols for the AST."""
|
2
|
+
|
3
|
+
from abc import ABC, abstractmethod
|
4
|
+
from typing import Any, Iterable, List, Optional, Protocol, TypeVar, Generic, runtime_checkable, Dict, Union, Tuple
|
5
|
+
|
6
|
+
from ..utils.source_location import SourceLocation
|
7
|
+
|
8
|
+
# Visitor pattern type variable
|
9
|
+
T_VisitorResult = TypeVar('T_VisitorResult')
|
10
|
+
|
11
|
+
class IVisitor(Protocol, Generic[T_VisitorResult]):
|
12
|
+
"""Protocol for AST visitors."""
|
13
|
+
|
14
|
+
def visit(self, node: 'IAstNode') -> T_VisitorResult:
|
15
|
+
"""Visit an AST node."""
|
16
|
+
...
|
17
|
+
|
18
|
+
@runtime_checkable
|
19
|
+
class IAstNode(Protocol):
|
20
|
+
"""Protocol defining the minimum interface for an AST node."""
|
21
|
+
|
22
|
+
location: Optional[SourceLocation]
|
23
|
+
|
24
|
+
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
25
|
+
"""Accept a visitor (Visitor Pattern)."""
|
26
|
+
...
|
27
|
+
|
28
|
+
def get_children(self) -> Iterable['IAstNode']:
|
29
|
+
"""Get child nodes of this node."""
|
30
|
+
...
|
31
|
+
|
32
|
+
def get_child_by_name(self, name: str) -> Optional['IAstNode']:
|
33
|
+
"""Get a child node by its field name."""
|
34
|
+
...
|
35
|
+
|
36
|
+
def get_child_names(self) -> List[str]:
|
37
|
+
"""Get the names of all child fields."""
|
38
|
+
...
|
39
|
+
|
40
|
+
def get_parent(self) -> Optional['IAstNode']:
|
41
|
+
"""Get the parent node, if available."""
|
42
|
+
...
|
43
|
+
|
44
|
+
def get_attributes(self) -> Dict[str, Any]:
|
45
|
+
"""Get all attributes of this node as a dictionary."""
|
46
|
+
...
|
47
|
+
|
48
|
+
def to_dict(self) -> Dict[str, Any]:
|
49
|
+
"""
|
50
|
+
Convert the node to a dictionary representation.
|
51
|
+
|
52
|
+
This is an optional method for serialization support.
|
53
|
+
|
54
|
+
Returns:
|
55
|
+
A dictionary representation of the node
|
56
|
+
"""
|
57
|
+
...
|
58
|
+
|
59
|
+
@runtime_checkable
|
60
|
+
class IExpression(IAstNode, Protocol):
|
61
|
+
"""Protocol for expression nodes."""
|
62
|
+
pass
|
63
|
+
|
64
|
+
@runtime_checkable
|
65
|
+
class IStatement(IAstNode, Protocol):
|
66
|
+
"""Protocol for statement nodes."""
|
67
|
+
pass
|
68
|
+
|
69
|
+
@runtime_checkable
|
70
|
+
class ILiteral(IExpression, Protocol):
|
71
|
+
"""Protocol for literal value nodes."""
|
72
|
+
value: Any
|
73
|
+
|
74
|
+
def get_value(self) -> Any:
|
75
|
+
"""Get the literal value."""
|
76
|
+
...
|
77
|
+
|
78
|
+
@runtime_checkable
|
79
|
+
class IIdentifier(IExpression, Protocol):
|
80
|
+
"""Protocol for identifier nodes."""
|
81
|
+
name: str
|
82
|
+
|
83
|
+
def get_name(self) -> str:
|
84
|
+
"""Get the identifier name."""
|
85
|
+
...
|
86
|
+
|
87
|
+
@runtime_checkable
|
88
|
+
class IConditionalExpression(IExpression, Protocol):
|
89
|
+
"""Protocol for conditional expression (ternary operator) nodes."""
|
90
|
+
|
91
|
+
def get_condition(self) -> IExpression:
|
92
|
+
"""Get the condition expression."""
|
93
|
+
...
|
94
|
+
|
95
|
+
def get_true_expression(self) -> IExpression:
|
96
|
+
"""Get the expression to evaluate if condition is true."""
|
97
|
+
...
|
98
|
+
|
99
|
+
def get_false_expression(self) -> IExpression:
|
100
|
+
"""Get the expression to evaluate if condition is false."""
|
101
|
+
...
|
102
|
+
|
103
|
+
@runtime_checkable
|
104
|
+
class IFunctionCall(IExpression, Protocol):
|
105
|
+
"""Protocol for function call nodes."""
|
106
|
+
|
107
|
+
def get_function_expr(self) -> IExpression:
|
108
|
+
"""Get the function expression."""
|
109
|
+
...
|
110
|
+
|
111
|
+
def get_arguments(self) -> List[IExpression]:
|
112
|
+
"""Get the positional arguments."""
|
113
|
+
...
|
114
|
+
|
115
|
+
def get_keyword_arguments(self) -> Dict[str, IExpression]:
|
116
|
+
"""Get the keyword arguments as a dictionary."""
|
117
|
+
...
|
118
|
+
|
119
|
+
@runtime_checkable
|
120
|
+
class IAssignment(IStatement, Protocol):
|
121
|
+
"""Protocol for assignment nodes."""
|
122
|
+
|
123
|
+
def get_target(self) -> IExpression:
|
124
|
+
"""Get the assignment target."""
|
125
|
+
...
|
126
|
+
|
127
|
+
def get_value(self) -> IExpression:
|
128
|
+
"""Get the assigned value."""
|
129
|
+
...
|
130
|
+
|
131
|
+
class AstNode(ABC):
|
132
|
+
"""Abstract base implementation of the IAstNode protocol."""
|
133
|
+
|
134
|
+
def __init__(self, location: Optional[SourceLocation] = None):
|
135
|
+
self.location = location
|
136
|
+
self._parent: Optional[IAstNode] = None
|
137
|
+
|
138
|
+
@abstractmethod
|
139
|
+
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
140
|
+
"""Accept a visitor (Visitor Pattern)."""
|
141
|
+
pass
|
142
|
+
|
143
|
+
@abstractmethod
|
144
|
+
def get_children(self) -> List[IAstNode]:
|
145
|
+
"""Get child nodes of this node."""
|
146
|
+
pass
|
147
|
+
|
148
|
+
def get_child_by_name(self, name: str) -> Optional[IAstNode]:
|
149
|
+
"""Get a child node by its field name."""
|
150
|
+
if not hasattr(self, '_fields') or name not in getattr(self, '_fields'):
|
151
|
+
return None
|
152
|
+
|
153
|
+
value = getattr(self, name, None)
|
154
|
+
if isinstance(value, IAstNode):
|
155
|
+
return value
|
156
|
+
elif isinstance(value, list) and value and isinstance(value[0], IAstNode):
|
157
|
+
return value[0] # Return first item if it's a list of nodes
|
158
|
+
|
159
|
+
return None
|
160
|
+
|
161
|
+
def get_child_names(self) -> List[str]:
|
162
|
+
"""Get the names of all child fields."""
|
163
|
+
if not hasattr(self, '_fields'):
|
164
|
+
return []
|
165
|
+
return list(getattr(self, '_fields'))
|
166
|
+
|
167
|
+
def get_parent(self) -> Optional[IAstNode]:
|
168
|
+
"""Get the parent node, if available."""
|
169
|
+
return getattr(self, '_parent', None)
|
170
|
+
|
171
|
+
def set_parent(self, parent: IAstNode) -> None:
|
172
|
+
"""Set the parent node reference."""
|
173
|
+
self._parent = parent
|
174
|
+
|
175
|
+
def get_attributes(self) -> Dict[str, Any]:
|
176
|
+
"""Get all attributes of this node as a dictionary."""
|
177
|
+
result = {}
|
178
|
+
if hasattr(self, '_fields'):
|
179
|
+
for field in getattr(self, '_fields'):
|
180
|
+
result[field] = getattr(self, field, None)
|
181
|
+
return result
|
182
|
+
|
183
|
+
def __eq__(self, other: Any) -> bool:
|
184
|
+
"""Compare nodes for equality."""
|
185
|
+
if not isinstance(other, self.__class__):
|
186
|
+
return NotImplemented
|
187
|
+
|
188
|
+
# Compare all attributes defined in _fields
|
189
|
+
if hasattr(self, '_fields'):
|
190
|
+
for field in getattr(self, '_fields'):
|
191
|
+
if getattr(self, field, None) != getattr(other, field, None):
|
192
|
+
return False
|
193
|
+
|
194
|
+
# Compare location
|
195
|
+
return self.location == other.location
|
196
|
+
|
197
|
+
def to_dict(self) -> Dict[str, Any]:
|
198
|
+
"""
|
199
|
+
Convert the node to a dictionary representation.
|
200
|
+
|
201
|
+
This implementation uses the serialization visitor to create a
|
202
|
+
dictionary representation of the node.
|
203
|
+
|
204
|
+
Returns:
|
205
|
+
A dictionary representation of the node
|
206
|
+
"""
|
207
|
+
from ..serialization.json_serializer import serialize_ast_to_dict
|
208
|
+
return serialize_ast_to_dict(self)
|
vex_ast/ast/literals.py
CHANGED
@@ -1,80 +1,80 @@
|
|
1
|
-
"""Literal value nodes for the AST."""
|
2
|
-
|
3
|
-
from typing import Any, List, Optional, Union
|
4
|
-
|
5
|
-
from .interfaces import IAstNode, IVisitor, T_VisitorResult, ILiteral
|
6
|
-
from .core import Expression
|
7
|
-
from ..utils.source_location import SourceLocation
|
8
|
-
|
9
|
-
class Literal(Expression, ILiteral):
|
10
|
-
"""Base class for all literal values."""
|
11
|
-
|
12
|
-
_fields = ('value',)
|
13
|
-
|
14
|
-
def __init__(self, value: Any, location: Optional[SourceLocation] = None):
|
15
|
-
super().__init__(location)
|
16
|
-
self.value = value
|
17
|
-
|
18
|
-
def get_children(self) -> List[IAstNode]:
|
19
|
-
"""Literals have no children."""
|
20
|
-
return []
|
21
|
-
|
22
|
-
def get_value(self) -> Any:
|
23
|
-
"""Get the literal value."""
|
24
|
-
return self.value
|
25
|
-
|
26
|
-
class NumberLiteral(Literal):
|
27
|
-
"""A numeric literal (integer or float)."""
|
28
|
-
|
29
|
-
def __init__(self, value: Union[int, float], location: Optional[SourceLocation] = None):
|
30
|
-
super().__init__(value, location)
|
31
|
-
|
32
|
-
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
33
|
-
return visitor.visit_numberliteral(self)
|
34
|
-
|
35
|
-
def is_integer(self) -> bool:
|
36
|
-
"""Check if this is an integer literal."""
|
37
|
-
return isinstance(self.value, int)
|
38
|
-
|
39
|
-
def is_float(self) -> bool:
|
40
|
-
"""Check if this is a float literal."""
|
41
|
-
return isinstance(self.value, float)
|
42
|
-
|
43
|
-
class StringLiteral(Literal):
|
44
|
-
"""A string literal."""
|
45
|
-
|
46
|
-
def __init__(self, value: str, location: Optional[SourceLocation] = None):
|
47
|
-
super().__init__(value, location)
|
48
|
-
|
49
|
-
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
50
|
-
return visitor.visit_stringliteral(self)
|
51
|
-
|
52
|
-
def get_length(self) -> int:
|
53
|
-
"""Get the length of the string."""
|
54
|
-
return len(self.value)
|
55
|
-
|
56
|
-
class BooleanLiteral(Literal):
|
57
|
-
"""A boolean literal (True or False)."""
|
58
|
-
|
59
|
-
def __init__(self, value: bool, location: Optional[SourceLocation] = None):
|
60
|
-
super().__init__(value, location)
|
61
|
-
|
62
|
-
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
63
|
-
return visitor.visit_booleanliteral(self)
|
64
|
-
|
65
|
-
def is_true(self) -> bool:
|
66
|
-
"""Check if this is a True literal."""
|
67
|
-
return self.value is True
|
68
|
-
|
69
|
-
def is_false(self) -> bool:
|
70
|
-
"""Check if this is a False literal."""
|
71
|
-
return self.value is False
|
72
|
-
|
73
|
-
class NoneLiteral(Literal):
|
74
|
-
"""A None literal."""
|
75
|
-
|
76
|
-
def __init__(self, location: Optional[SourceLocation] = None):
|
77
|
-
super().__init__(None, location)
|
78
|
-
|
79
|
-
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
80
|
-
return visitor.visit_noneliteral(self)
|
1
|
+
"""Literal value nodes for the AST."""
|
2
|
+
|
3
|
+
from typing import Any, List, Optional, Union
|
4
|
+
|
5
|
+
from .interfaces import IAstNode, IVisitor, T_VisitorResult, ILiteral
|
6
|
+
from .core import Expression
|
7
|
+
from ..utils.source_location import SourceLocation
|
8
|
+
|
9
|
+
class Literal(Expression, ILiteral):
|
10
|
+
"""Base class for all literal values."""
|
11
|
+
|
12
|
+
_fields = ('value',)
|
13
|
+
|
14
|
+
def __init__(self, value: Any, location: Optional[SourceLocation] = None):
|
15
|
+
super().__init__(location)
|
16
|
+
self.value = value
|
17
|
+
|
18
|
+
def get_children(self) -> List[IAstNode]:
|
19
|
+
"""Literals have no children."""
|
20
|
+
return []
|
21
|
+
|
22
|
+
def get_value(self) -> Any:
|
23
|
+
"""Get the literal value."""
|
24
|
+
return self.value
|
25
|
+
|
26
|
+
class NumberLiteral(Literal):
|
27
|
+
"""A numeric literal (integer or float)."""
|
28
|
+
|
29
|
+
def __init__(self, value: Union[int, float], location: Optional[SourceLocation] = None):
|
30
|
+
super().__init__(value, location)
|
31
|
+
|
32
|
+
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
33
|
+
return visitor.visit_numberliteral(self)
|
34
|
+
|
35
|
+
def is_integer(self) -> bool:
|
36
|
+
"""Check if this is an integer literal."""
|
37
|
+
return isinstance(self.value, int)
|
38
|
+
|
39
|
+
def is_float(self) -> bool:
|
40
|
+
"""Check if this is a float literal."""
|
41
|
+
return isinstance(self.value, float)
|
42
|
+
|
43
|
+
class StringLiteral(Literal):
|
44
|
+
"""A string literal."""
|
45
|
+
|
46
|
+
def __init__(self, value: str, location: Optional[SourceLocation] = None):
|
47
|
+
super().__init__(value, location)
|
48
|
+
|
49
|
+
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
50
|
+
return visitor.visit_stringliteral(self)
|
51
|
+
|
52
|
+
def get_length(self) -> int:
|
53
|
+
"""Get the length of the string."""
|
54
|
+
return len(self.value)
|
55
|
+
|
56
|
+
class BooleanLiteral(Literal):
|
57
|
+
"""A boolean literal (True or False)."""
|
58
|
+
|
59
|
+
def __init__(self, value: bool, location: Optional[SourceLocation] = None):
|
60
|
+
super().__init__(value, location)
|
61
|
+
|
62
|
+
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
63
|
+
return visitor.visit_booleanliteral(self)
|
64
|
+
|
65
|
+
def is_true(self) -> bool:
|
66
|
+
"""Check if this is a True literal."""
|
67
|
+
return self.value is True
|
68
|
+
|
69
|
+
def is_false(self) -> bool:
|
70
|
+
"""Check if this is a False literal."""
|
71
|
+
return self.value is False
|
72
|
+
|
73
|
+
class NoneLiteral(Literal):
|
74
|
+
"""A None literal."""
|
75
|
+
|
76
|
+
def __init__(self, location: Optional[SourceLocation] = None):
|
77
|
+
super().__init__(None, location)
|
78
|
+
|
79
|
+
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
80
|
+
return visitor.visit_noneliteral(self)
|