vex-ast 0.2.2__py3-none-any.whl → 0.2.3__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/ast/vex_nodes.py CHANGED
@@ -91,8 +91,21 @@ class VexAPICall(FunctionCall):
91
91
  return False, self._validation_error
92
92
 
93
93
  # Convert args and kwargs to appropriate format
94
- arg_values = [arg for arg in self.args]
95
- kwarg_values = {kw.name: kw.value for kw in self.keywords or []}
94
+ arg_values = []
95
+ for arg in self.args:
96
+ # For string literals, use their actual string value for validation
97
+ if hasattr(arg, 'value') and hasattr(arg, '__class__') and arg.__class__.__name__ == 'StringLiteral':
98
+ arg_values.append(arg.value)
99
+ else:
100
+ arg_values.append(arg)
101
+
102
+ kwarg_values = {}
103
+ for kw in (self.keywords or []):
104
+ # For string literals, use their actual string value for validation
105
+ if hasattr(kw.value, 'value') and hasattr(kw.value, '__class__') and kw.value.__class__.__name__ == 'StringLiteral':
106
+ kwarg_values[kw.name] = kw.value.value
107
+ else:
108
+ kwarg_values[kw.name] = kw.value
96
109
 
97
110
  # Validate against the signature
98
111
  valid, error = signature.validate_arguments(arg_values, kwarg_values)
vex_ast/parser/factory.py CHANGED
@@ -123,6 +123,12 @@ class NodeFactory:
123
123
  """Create a function definition node."""
124
124
  return FunctionDefinition(name, args, body, return_annotation, location)
125
125
 
126
+ def create_argument(self, name: str, annotation: Optional[Expression] = None,
127
+ default: Optional[Expression] = None,
128
+ location: Optional[SourceLocation] = None) -> Argument:
129
+ """Create an argument node."""
130
+ return Argument(name, annotation, default, location)
131
+
126
132
  def create_return_statement(self, value: Optional[Expression] = None,
127
133
  location: Optional[SourceLocation] = None) -> ReturnStatement:
128
134
  """Create a return statement node."""
@@ -176,4 +182,4 @@ class NodeFactory:
176
182
  return Program(body, location)
177
183
 
178
184
  # Global factory instance for simple use cases
179
- default_factory = NodeFactory()
185
+ default_factory = NodeFactory()
@@ -692,7 +692,13 @@ class PythonParser(BaseParser):
692
692
  f"Syntax error: {e.msg}",
693
693
  loc
694
694
  )
695
- raise VexSyntaxError(f"Syntax error: {e.msg}", loc) from e
695
+
696
+ # Only raise if the error handler is configured to do so
697
+ if self.error_handler._raise_on_error:
698
+ raise VexSyntaxError(f"Syntax error: {e.msg}", loc) from e
699
+
700
+ # Return an empty program if we're not raising
701
+ return self.factory.create_program([])
696
702
 
697
703
  except Exception as e:
698
704
  # Handle other parsing errors
@@ -138,6 +138,49 @@ class VexFunctionSignature:
138
138
  if param_name in kwargs:
139
139
  return False, f"Duplicate argument '{param_name}' for {self.name}"
140
140
 
141
- # TODO: Add type checking for arguments
141
+ # Type checking for arguments
142
+ from ..types.type_checker import type_checker
143
+ from ..types.enums import EnumType
144
+
145
+ # Check positional arguments
146
+ for i, arg in enumerate(args):
147
+ if i >= len(self.parameters):
148
+ break
149
+
150
+ param = self.parameters[i]
151
+ expected_type = param.type
152
+
153
+ # Handle string literals for enum types
154
+ if isinstance(expected_type, EnumType) and isinstance(arg, str):
155
+ if arg not in expected_type.values:
156
+ return False, f"Invalid enum value '{arg}' for parameter '{param.name}' in {self.name}"
157
+ continue
158
+
159
+ # Handle other types
160
+ if hasattr(arg, 'get_type'):
161
+ arg_type = arg.get_type()
162
+ if arg_type and not type_checker.is_compatible(arg_type, expected_type):
163
+ return False, f"Type mismatch for parameter '{param.name}' in {self.name}: expected {expected_type}, got {arg_type}"
164
+
165
+ # Check keyword arguments
166
+ for kwarg_name, kwarg_value in kwargs.items():
167
+ # Find the parameter
168
+ param = next((p for p in self.parameters if p.name == kwarg_name), None)
169
+ if not param:
170
+ continue # Already checked for unknown kwargs above
171
+
172
+ expected_type = param.type
173
+
174
+ # Handle string literals for enum types
175
+ if isinstance(expected_type, EnumType) and isinstance(kwarg_value, str):
176
+ if kwarg_value not in expected_type.values:
177
+ return False, f"Invalid enum value '{kwarg_value}' for parameter '{param.name}' in {self.name}"
178
+ continue
179
+
180
+ # Handle other types
181
+ if hasattr(kwarg_value, 'get_type'):
182
+ kwarg_type = kwarg_value.get_type()
183
+ if kwarg_type and not type_checker.is_compatible(kwarg_type, expected_type):
184
+ return False, f"Type mismatch for parameter '{param.name}' in {self.name}: expected {expected_type}, got {kwarg_type}"
142
185
 
143
186
  return True, None
@@ -10,7 +10,7 @@ from typing import Any, Dict, List, Optional, Type, Union, cast
10
10
  from ..ast.interfaces import IAstNode
11
11
  from ..parser.factory import NodeFactory
12
12
  from ..utils.source_location import SourceLocation
13
- from ..utils.errors import ErrorHandler
13
+ from ..utils.errors import ErrorHandler, ErrorType
14
14
 
15
15
 
16
16
  class DeserializationFactory:
@@ -153,6 +153,7 @@ class DeserializationFactory:
153
153
  "WhileLoop": self.node_factory.create_while_loop,
154
154
  "ForLoop": self.node_factory.create_for_loop,
155
155
  "FunctionDefinition": self.node_factory.create_function_definition,
156
+ "Argument": self.node_factory.create_argument,
156
157
  "ReturnStatement": self.node_factory.create_return_statement,
157
158
  "BreakStatement": self.node_factory.create_break_statement,
158
159
  "ContinueStatement": self.node_factory.create_continue_statement,
@@ -198,11 +199,21 @@ class DeserializationFactory:
198
199
  except TypeError as e:
199
200
  # If the factory method doesn't accept the kwargs, report an error
200
201
  if self.error_handler:
201
- self.error_handler.report_error(f"Failed to create {node_type}: {str(e)}")
202
+ self.error_handler.add_error(
203
+ error_type=ErrorType.INTERNAL_ERROR,
204
+ message=f"Failed to create {node_type}: {str(e)}"
205
+ )
202
206
  raise ValueError(f"Failed to deserialize {node_type}: {str(e)}")
203
207
 
204
208
  # Specific node creation methods for complex cases
205
209
 
210
+ def _create_attributeaccess(self, data: Dict[str, Any],
211
+ location: Optional[SourceLocation]) -> IAstNode:
212
+ """Create an AttributeAccess node from serialized data."""
213
+ object_expr = self._deserialize_value(data.get("object"))
214
+ attribute = data.get("attribute", "")
215
+ return self.node_factory.create_attribute_access(object_expr, attribute, location)
216
+
206
217
  def _create_program(self, data: Dict[str, Any],
207
218
  location: Optional[SourceLocation]) -> IAstNode:
208
219
  """Create a Program node from serialized data."""
@@ -453,16 +453,15 @@ def _generate_definitions() -> Dict[str, Any]:
453
453
  return definitions
454
454
 
455
455
 
456
- def export_schema_to_file(filepath: str, indent: int = 2) -> None:
456
+ def export_schema_to_file(schema: Dict[str, Any], filepath: str, indent: int = 2) -> None:
457
457
  """
458
- Save the generated schema to a file.
458
+ Save the schema to a file.
459
459
 
460
460
  Args:
461
+ schema: The schema to save
461
462
  filepath: The path to save the schema to
462
463
  indent: The indentation level for pretty-printing
463
464
  """
464
- schema = generate_ast_schema()
465
-
466
465
  # Ensure the directory exists
467
466
  os.makedirs(os.path.dirname(os.path.abspath(filepath)), exist_ok=True)
468
467
 
vex_ast/utils/errors.py CHANGED
@@ -50,7 +50,7 @@ class ErrorObserver(Protocol[T_Error]):
50
50
  class ErrorHandler:
51
51
  """Manages error collection and notification."""
52
52
 
53
- def __init__(self, raise_on_error: bool = False):
53
+ def __init__(self, raise_on_error: bool = True):
54
54
  self._errors: List[Error] = []
55
55
  self._raise_on_error = raise_on_error
56
56
  self._observers: List[ErrorObserver] = []
@@ -109,4 +109,4 @@ class VexSyntaxError(VexAstError):
109
109
 
110
110
  def __init__(self, message: str, location: Optional[SourceLocation] = None):
111
111
  self.location = location
112
- super().__init__(message)
112
+ super().__init__(message)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vex_ast
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: A Python package for generating Abstract Syntax Trees for VEX V5 code.
5
5
  Home-page: https://github.com/heartx2/vex_ast
6
6
  Author: Chaze
@@ -11,12 +11,12 @@ vex_ast/ast/navigator.py,sha256=9DaVXrknBbBr4omAAMHQnZL9Wpj5wjtoCS6_lni8MYM,7529
11
11
  vex_ast/ast/operators.py,sha256=I-yWvhsrz-OxmBZs5zIss_GTZF5S-nwcSmIzvAVtddM,3160
12
12
  vex_ast/ast/statements.py,sha256=OWRthjYGmTuNozYAHjh_Enp5t-hR1PphtPnFg31FeWw,11841
13
13
  vex_ast/ast/validators.py,sha256=ySpi5H0XRdGXXMFAfmuVEyc3Q9mMXhubZAkP4N8NL3c,4717
14
- vex_ast/ast/vex_nodes.py,sha256=HmUPfiogz0rnObyhg1XEsxPIDdM5xbNxl_kW9NND8pQ,11345
14
+ vex_ast/ast/vex_nodes.py,sha256=8Wq9vl8Mp70E3fxEut9tB6WZE1z0Q_i5V0qh_5Zoeag,11981
15
15
  vex_ast/parser/README.md,sha256=P1qq_97skpgluLDpNu9V_pAdkuF9StjkzOEXJJYpEuM,2565
16
16
  vex_ast/parser/__init__.py,sha256=LGHnFm3UzR4Nw7royGH3c_2RqeY66y8O6DdXHbm9yL4,504
17
- vex_ast/parser/factory.py,sha256=gaje0jOPu5lpndgX9c3VuQ_q-FJuFz9yC5y2bD69lL4,8770
17
+ vex_ast/parser/factory.py,sha256=ryTs8dQej8GbATyc7H4NUUISL1Bq65eIjyq84HaFTlo,9098
18
18
  vex_ast/parser/interfaces.py,sha256=Ttc0bD_5X420ZCT9MLUf_wE1aZLWLkaJRQqCwBy9wIs,956
19
- vex_ast/parser/python_parser.py,sha256=e1owk-c6Rb4Bt5SYcgB-urZzqsX5xC9tzcK1sB8gkr4,29687
19
+ vex_ast/parser/python_parser.py,sha256=EHcro2NqVLScOBBG0XuWUMiT7Dmqep4M9scGOxpJoYw,29947
20
20
  vex_ast/parser/strategies.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
21
  vex_ast/registry/README.md,sha256=J8xEXEscEZhWa6wmn05kjE395AjrV7p2h7nq4SXI5uE,1535
22
22
  vex_ast/registry/__init__.py,sha256=dXT8OS7uLyBSdQKZDWrtbANzgSWcg9HUQDA1EaLOvjQ,1188
@@ -24,7 +24,7 @@ vex_ast/registry/api.py,sha256=yyW-TsCIULTzePAoyMvEqD_RNlkFSb4PLpiSkw6ueQk,5460
24
24
  vex_ast/registry/categories.py,sha256=y5tnCzHQ9PPg9hOzOMgyE1ZAhcsjgeFSrgqdJrdqHEg,4885
25
25
  vex_ast/registry/language_map.py,sha256=eekN3k-K9g90GFi4--If3nfJCyarUJxDWDCDvLm7mdU,2656
26
26
  vex_ast/registry/registry.py,sha256=gvsQKyeXWp84T2uDB4O_WQgKCeq8W9udl8TD5MnPZzc,6661
27
- vex_ast/registry/signature.py,sha256=m8gQKdc5IaORDdfdBX6_qH1OL5LoTzveGoWlIIaOES0,5763
27
+ vex_ast/registry/signature.py,sha256=_Lde3bteVVdYG31fN4v62UViWSVyxi4U3mYT1-9b4A0,7881
28
28
  vex_ast/registry/simulation_behavior.py,sha256=WwkVKae0owtv3WTrfnVH93rpsh9lbqJ_RSAVmpIVA_k,313
29
29
  vex_ast/registry/validation.py,sha256=xq5UjSWYAcRxjxsCGg3WU5RtPN-DB-JAqKqDNGvnJGk,1973
30
30
  vex_ast/registry/functions/__init__.py,sha256=X9aw0-Y9Q6Gcx01zepP8G_20ybfwC-LDPQfkK2RDOrE,207
@@ -35,9 +35,9 @@ vex_ast/registry/functions/motor.py,sha256=Vby44hV1goNFgFQEFDlv7z_9uGQeuvLMABplO
35
35
  vex_ast/registry/functions/sensors.py,sha256=BdhLV5gSWD5HO-o3JRXhbGQF7s1Ybk3b6VLLqVau1i0,6410
36
36
  vex_ast/registry/functions/timing.py,sha256=DqwMVPk7VKDeZB4S3NI7wOYgM1R52dcdgaVIb9135Jg,3204
37
37
  vex_ast/serialization/__init__.py,sha256=qPTEiMjU8hpVxNH5z4MY7Yj60AxuFurjXZStjhWWf6o,835
38
- vex_ast/serialization/json_deserializer.py,sha256=m_xiEUEoFXGfFylK3M8BVs7F2EieQJ9wbUa_ZTpkHtQ,10523
38
+ vex_ast/serialization/json_deserializer.py,sha256=GCfm8XAF_90FswlizFy59fyZwjZtE94yPR_FWWWAE20,11108
39
39
  vex_ast/serialization/json_serializer.py,sha256=YvMRUpqXjtbxlIvathEIywUqbH3Ne6GSRODfFB0QCGM,4465
40
- vex_ast/serialization/schema.py,sha256=zpKujT7u3Qw2kNbwjV09lNzeQAsCxvMx-uAdaRMEstA,14431
40
+ vex_ast/serialization/schema.py,sha256=BNBYruht3fmuGoVGv5fuMwdIEqLu7OZ1XZS8gzdom0w,14440
41
41
  vex_ast/types/README.md,sha256=Wd3jBShiNXNc3iJ69Qps5_0mBq8QVEd_Gz5OachfS34,1029
42
42
  vex_ast/types/__init__.py,sha256=naLOT_-qHWxzYj4nwxjCB5dfL6tcIt7TjMEaRaXMWbU,2163
43
43
  vex_ast/types/base.py,sha256=hCPCeBNnD5p29Mim-ouRTkG6Lfa8NXrsdYLO8xsbFtM,2258
@@ -47,7 +47,7 @@ vex_ast/types/primitives.py,sha256=t_4kEVyPSmKRHEIRQcp-X5Yq46JbG1SxzlvHb0vL4IA,1
47
47
  vex_ast/types/type_checker.py,sha256=emzhmc6AlH71w0DrKLlZRMBlJNZAuENihvRXTenqg_Q,1083
48
48
  vex_ast/utils/README.md,sha256=Y9RJMQTqQbpjVkvYJmpeRihD1zfW9PhNL_LgoDJ84ak,1945
49
49
  vex_ast/utils/__init__.py,sha256=azzhhFoMykqOkVVm6X2V7dFW3jGBkOvEgnEP1JTCS3g,621
50
- vex_ast/utils/errors.py,sha256=uq_jyu-YasifXjKSpPbVxup-XFf0XSHmp7A0Zd87TUY,3850
50
+ vex_ast/utils/errors.py,sha256=T1sOqWR3-0dYqmXAKDwO7VXIHCGZMnF_gEIGmFWy8Ps,3850
51
51
  vex_ast/utils/source_location.py,sha256=r857ypqUBqex2y_R0RzZo7pz5di9qtEeWFFQ4HwzYQE,1297
52
52
  vex_ast/utils/type_definitions.py,sha256=2rB85B1vZL1GLWItBuJJpyr-vmp3W346EMMX2TPZ99Q,313
53
53
  vex_ast/visitors/README.md,sha256=BKDj8LMuBlCrzgSSLmCkbET7WIqgxe-oCkqQbqXekrE,2725
@@ -56,8 +56,8 @@ vex_ast/visitors/analyzer.py,sha256=cBT5PRbtfQ_Dt1qiHN-wdO5KnC2yl-Ul5RasXg9geHY,
56
56
  vex_ast/visitors/base.py,sha256=Ph0taTIVMHV_QjXfDd0ipZnCXVJErkyRtPpfwfzo-kY,4859
57
57
  vex_ast/visitors/printer.py,sha256=CUY_73hxm7MoC-63JeIXaVYnZ8QqtfMqbek2R2HMEmE,5411
58
58
  vex_ast/visitors/transformer.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
- vex_ast-0.2.2.dist-info/licenses/LICENSE,sha256=IOSlfCuxGv4OAg421BRDKVi16RZ7-5kCMJ4B16r4kuc,69
60
- vex_ast-0.2.2.dist-info/METADATA,sha256=Rftzrxm-exQp3zpV5wcNVkErbkQn1ww0pz65tXOQhDw,5295
61
- vex_ast-0.2.2.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
62
- vex_ast-0.2.2.dist-info/top_level.txt,sha256=MoZGrpKgNUDiqL9gWp4q3wMw3q93XPEEjmBNPJQcNAs,8
63
- vex_ast-0.2.2.dist-info/RECORD,,
59
+ vex_ast-0.2.3.dist-info/licenses/LICENSE,sha256=IOSlfCuxGv4OAg421BRDKVi16RZ7-5kCMJ4B16r4kuc,69
60
+ vex_ast-0.2.3.dist-info/METADATA,sha256=2TsjEVVuPN94XQ8QOW5bHItBbFh3IAvn1uuCoEJe8nQ,5295
61
+ vex_ast-0.2.3.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
62
+ vex_ast-0.2.3.dist-info/top_level.txt,sha256=MoZGrpKgNUDiqL9gWp4q3wMw3q93XPEEjmBNPJQcNAs,8
63
+ vex_ast-0.2.3.dist-info/RECORD,,