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
@@ -1,146 +1,196 @@
1
- """AST printing visitor implementation."""
2
-
3
- import io
4
- from typing import Any, List, Optional
5
-
6
- from .base import AstVisitor
7
- from ..ast.interfaces import IAstNode
8
-
9
- class PrintVisitor(AstVisitor[str]):
10
- """Visitor that generates a readable string representation of the AST."""
11
-
12
- def __init__(self):
13
- self._output = io.StringIO()
14
- self._indent_level = 0
15
-
16
- def _indent(self) -> None:
17
- """Write the current indentation."""
18
- self._output.write(' ' * self._indent_level)
19
-
20
- def _write_node_header(self, node: IAstNode, name: str) -> None:
21
- """Write a standard node header with location info."""
22
- self._indent()
23
- self._output.write(f"{name}")
24
- if node.location:
25
- self._output.write(f" (at {node.location})")
26
- self._output.write(":\n")
27
-
28
- def _format_value(self, value: Any) -> str:
29
- """Format a basic value for display."""
30
- return repr(value)
31
-
32
- def generic_visit(self, node: IAstNode) -> str:
33
- """Default node visitor that displays type and attributes."""
34
- node_name = node.__class__.__name__
35
- self._write_node_header(node, node_name)
36
-
37
- # Visit fields if present
38
- if hasattr(node, '_fields'):
39
- self._indent_level += 1
40
- for field_name in node._fields:
41
- value = getattr(node, field_name, None)
42
-
43
- # Skip None values
44
- if value is None:
45
- continue
46
-
47
- self._indent()
48
- self._output.write(f"{field_name} = ")
49
-
50
- if isinstance(value, IAstNode):
51
- self._output.write("\n")
52
- self.visit(value)
53
- elif isinstance(value, list):
54
- if not value:
55
- self._output.write("[]\n")
56
- else:
57
- self._output.write("[\n")
58
- self._indent_level += 1
59
- for i, item in enumerate(value):
60
- self._indent()
61
- self._output.write(f"[{i}]: ")
62
- if isinstance(item, IAstNode):
63
- self._output.write("\n")
64
- self.visit(item)
65
- else:
66
- self._output.write(f"{self._format_value(item)}\n")
67
- self._indent_level -= 1
68
- self._indent()
69
- self._output.write("]\n")
70
- else:
71
- self._output.write(f"{self._format_value(value)}\n")
72
- self._indent_level -= 1
73
-
74
- # At the root level, return the accumulated output
75
- if self._indent_level == 0:
76
- return self._output.getvalue()
77
- return ""
78
-
79
- # Simple node visitors for concise output
80
- def visit_identifier(self, node: Any) -> str:
81
- self._output.write(f"Identifier(name={node.name!r})")
82
- if node.location:
83
- self._output.write(f" (at {node.location})")
84
- return ""
85
-
86
- def visit_numberliteral(self, node: Any) -> str:
87
- self._output.write(f"NumberLiteral(value={node.value!r})")
88
- if node.location:
89
- self._output.write(f" (at {node.location})")
90
- return ""
91
-
92
- def visit_stringliteral(self, node: Any) -> str:
93
- self._output.write(f"StringLiteral(value={node.value!r})")
94
- if node.location:
95
- self._output.write(f" (at {node.location})")
96
- return ""
97
-
98
- def visit_booleanliteral(self, node: Any) -> str:
99
- self._output.write(f"BooleanLiteral(value={node.value!r})")
100
- if node.location:
101
- self._output.write(f" (at {node.location})")
102
- return ""
103
-
104
- def visit_noneliteral(self, node: Any) -> str:
105
- self._output.write(f"NoneLiteral()")
106
- if node.location:
107
- self._output.write(f" (at {node.location})")
108
- return ""
109
-
110
- # Program node is the entry point
111
- def visit_program(self, node: Any) -> str:
112
- self._output.write("Program:\n")
113
- self._indent_level += 1
114
- for i, stmt in enumerate(node.body):
115
- self._indent()
116
- self._output.write(f"[{i}]: \n")
117
- self._indent_level += 1
118
- self.visit(stmt)
119
- self._indent_level -= 1
120
- self._indent_level -= 1
121
- return self._output.getvalue()
122
-
123
- # Delegate all other methods to generic_visit
124
- visit_expression = generic_visit
125
- visit_statement = generic_visit
126
- visit_variablereference = generic_visit
127
- visit_binaryoperation = generic_visit
128
- visit_unaryoperation = generic_visit
129
- visit_conditionalexpression = generic_visit
130
- visit_functioncall = generic_visit
131
- visit_keywordargument = generic_visit
132
- visit_expressionstatement = generic_visit
133
- visit_assignment = generic_visit
134
- visit_ifstatement = generic_visit
135
- visit_whileloop = generic_visit
136
- visit_forloop = generic_visit
137
- visit_functiondefinition = generic_visit
138
- visit_argument = generic_visit
139
- visit_returnstatement = generic_visit
140
- visit_breakstatement = generic_visit
141
- visit_continuestatement = generic_visit
142
- visit_vexapicall = generic_visit
143
- visit_motorcontrol = generic_visit
144
- visit_sensorreading = generic_visit
145
- visit_timingcontrol = generic_visit
146
- visit_displayoutput = generic_visit
1
+ """AST printing visitor implementation."""
2
+
3
+ import io
4
+ from typing import Any, List, Optional
5
+
6
+ from .base import AstVisitor
7
+ from ..ast.interfaces import IAstNode
8
+
9
+ class PrintVisitor(AstVisitor[str]):
10
+ """Visitor that generates a readable string representation of the AST."""
11
+
12
+ def __init__(self):
13
+ self._output = io.StringIO()
14
+ self._indent_level = 0
15
+
16
+ def _indent(self) -> None:
17
+ """Write the current indentation."""
18
+ self._output.write(' ' * self._indent_level)
19
+
20
+ def _write_node_header(self, node: IAstNode, name: str) -> None:
21
+ """Write a standard node header with location info."""
22
+ self._indent()
23
+ self._output.write(f"{name}")
24
+ if node.location:
25
+ self._output.write(f" (at {node.location})")
26
+ self._output.write(":\n")
27
+
28
+ def _format_value(self, value: Any) -> str:
29
+ """Format a basic value for display."""
30
+ return repr(value)
31
+
32
+ def generic_visit(self, node: IAstNode) -> str:
33
+ """Default node visitor that displays type and attributes."""
34
+ node_name = node.__class__.__name__
35
+ self._write_node_header(node, node_name)
36
+
37
+ # Visit fields if present
38
+ if hasattr(node, '_fields'):
39
+ self._indent_level += 1
40
+ for field_name in node._fields:
41
+ value = getattr(node, field_name, None)
42
+
43
+ # Skip None values
44
+ if value is None:
45
+ continue
46
+
47
+ self._indent()
48
+ self._output.write(f"{field_name} = ")
49
+
50
+ if isinstance(value, IAstNode):
51
+ self._output.write("\n")
52
+ self.visit(value)
53
+ elif isinstance(value, list):
54
+ if not value:
55
+ self._output.write("[]\n")
56
+ else:
57
+ self._output.write("[\n")
58
+ self._indent_level += 1
59
+ for i, item in enumerate(value):
60
+ self._indent()
61
+ self._output.write(f"[{i}]: ")
62
+ if isinstance(item, IAstNode):
63
+ self._output.write("\n")
64
+ self.visit(item)
65
+ else:
66
+ self._output.write(f"{self._format_value(item)}\n")
67
+ self._indent_level -= 1
68
+ self._indent()
69
+ self._output.write("]\n")
70
+ else:
71
+ self._output.write(f"{self._format_value(value)}\n")
72
+ self._indent_level -= 1
73
+
74
+ # At the root level, return the accumulated output
75
+ if self._indent_level == 0:
76
+ return self._output.getvalue()
77
+ return ""
78
+
79
+ # Simple node visitors for concise output
80
+ def visit_identifier(self, node: Any) -> str:
81
+ self._output.write(f"Identifier(name={node.name!r})")
82
+ if node.location:
83
+ self._output.write(f" (at {node.location})")
84
+ return ""
85
+
86
+ def visit_numberliteral(self, node: Any) -> str:
87
+ self._output.write(f"NumberLiteral(value={node.value!r})")
88
+ if node.location:
89
+ self._output.write(f" (at {node.location})")
90
+ return ""
91
+
92
+ def visit_stringliteral(self, node: Any) -> str:
93
+ self._output.write(f"StringLiteral(value={node.value!r})")
94
+ if node.location:
95
+ self._output.write(f" (at {node.location})")
96
+ return ""
97
+
98
+ def visit_booleanliteral(self, node: Any) -> str:
99
+ self._output.write(f"BooleanLiteral(value={node.value!r})")
100
+ if node.location:
101
+ self._output.write(f" (at {node.location})")
102
+ return ""
103
+
104
+ def visit_noneliteral(self, node: Any) -> str:
105
+ self._output.write(f"NoneLiteral()")
106
+ if node.location:
107
+ self._output.write(f" (at {node.location})")
108
+ return ""
109
+
110
+ # Program node is the entry point
111
+ def visit_program(self, node: Any) -> str:
112
+ self._output.write("Program:\n")
113
+ self._indent_level += 1
114
+ for i, stmt in enumerate(node.body):
115
+ self._indent()
116
+ self._output.write(f"[{i}]: \n")
117
+ self._indent_level += 1
118
+ self.visit(stmt)
119
+ self._indent_level -= 1
120
+ self._indent_level -= 1
121
+ return self._output.getvalue()
122
+
123
+ # Delegate all other methods to generic_visit
124
+ visit_expression = generic_visit
125
+ visit_statement = generic_visit
126
+ visit_variablereference = generic_visit
127
+ visit_binaryoperation = generic_visit
128
+ visit_unaryoperation = generic_visit
129
+
130
+ def visit_conditionalexpression(self, node: Any) -> str:
131
+ """Custom visitor for conditional expressions to make them more readable."""
132
+ self._output.write("ConditionalExpression:\n")
133
+ self._indent_level += 1
134
+
135
+ # Print condition
136
+ self._indent()
137
+ self._output.write("condition = ")
138
+ self.visit(node.condition)
139
+ self._output.write("\n")
140
+
141
+ # Print true expression
142
+ self._indent()
143
+ self._output.write("true_expr = ")
144
+ self.visit(node.true_expr)
145
+ self._output.write("\n")
146
+
147
+ # Print false expression
148
+ self._indent()
149
+ self._output.write("false_expr = ")
150
+ self.visit(node.false_expr)
151
+ self._output.write("\n")
152
+
153
+ # Add the formatted Python conditional expression with if/else keywords
154
+ self._indent()
155
+ self._output.write("formatted = ")
156
+
157
+ # Capture the string representation of each part
158
+ true_str = io.StringIO()
159
+ old_output = self._output
160
+ self._output = true_str
161
+ self.visit(node.true_expr)
162
+
163
+ cond_str = io.StringIO()
164
+ self._output = cond_str
165
+ self.visit(node.condition)
166
+
167
+ false_str = io.StringIO()
168
+ self._output = false_str
169
+ self.visit(node.false_expr)
170
+
171
+ # Restore the original output
172
+ self._output = old_output
173
+
174
+ # Write the formatted conditional expression with if/else keywords
175
+ self._output.write(f"{true_str.getvalue()} if {cond_str.getvalue()} else {false_str.getvalue()}\n")
176
+
177
+ self._indent_level -= 1
178
+ return ""
179
+
180
+ visit_functioncall = generic_visit
181
+ visit_keywordargument = generic_visit
182
+ visit_expressionstatement = generic_visit
183
+ visit_assignment = generic_visit
184
+ visit_ifstatement = generic_visit
185
+ visit_whileloop = generic_visit
186
+ visit_forloop = generic_visit
187
+ visit_functiondefinition = generic_visit
188
+ visit_argument = generic_visit
189
+ visit_returnstatement = generic_visit
190
+ visit_breakstatement = generic_visit
191
+ visit_continuestatement = generic_visit
192
+ visit_vexapicall = generic_visit
193
+ visit_motorcontrol = generic_visit
194
+ visit_sensorreading = generic_visit
195
+ visit_timingcontrol = generic_visit
196
+ visit_displayoutput = generic_visit