vex-ast 0.2.5__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 -81
  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 -121
  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 -831
  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 -35
  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 -31
  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 -284
  39. vex_ast/serialization/json_serializer.py +148 -148
  40. vex_ast/serialization/schema.py +492 -492
  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 -122
  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 -196
  58. {vex_ast-0.2.5.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.5.dist-info/RECORD +0 -64
  61. {vex_ast-0.2.5.dist-info → vex_ast-0.2.6.dist-info}/WHEEL +0 -0
  62. {vex_ast-0.2.5.dist-info → vex_ast-0.2.6.dist-info}/licenses/LICENSE +0 -0
  63. {vex_ast-0.2.5.dist-info → vex_ast-0.2.6.dist-info}/top_level.txt +0 -0
@@ -1,191 +1,269 @@
1
- from typing import Optional, List, Dict, Any, Union, Callable, Tuple
2
- from enum import Enum, auto
3
- from ..types.base import VexType, VOID, ANY
4
-
5
- class ParameterMode(Enum):
6
- """Parameter passing modes"""
7
- VALUE = auto() # Pass by value
8
- REFERENCE = auto() # Pass by reference
9
- OUTPUT = auto() # Output parameter
10
-
11
- class VexFunctionParameter:
12
- """Represents a parameter in a VEX function signature"""
13
-
14
- def __init__(self,
15
- name: str,
16
- type_: VexType,
17
- default_value: Optional[Any] = None,
18
- mode: ParameterMode = ParameterMode.VALUE,
19
- description: str = ""):
20
- self.name = name
21
- self.type = type_
22
- self.default_value = default_value
23
- self.mode = mode
24
- self.description = description
25
- self.is_optional = default_value is not None
26
-
27
- @property
28
- def optional(self) -> bool:
29
- """Alias for is_optional for compatibility."""
30
- return self.is_optional
31
-
32
- def __str__(self) -> str:
33
- mode_str = ""
34
- if self.mode == ParameterMode.REFERENCE:
35
- mode_str = "&"
36
- elif self.mode == ParameterMode.OUTPUT:
37
- mode_str = "*"
38
-
39
- default_str = ""
40
- if self.is_optional:
41
- default_str = f" = {self.default_value}"
42
-
43
- return f"{self.type}{mode_str} {self.name}{default_str}"
44
-
45
- class SimulationCategory(Enum):
46
- """Categories for simulation behavior"""
47
- MOTOR_CONTROL = auto()
48
- SENSOR_READING = auto()
49
- DISPLAY_OUTPUT = auto()
50
- TIMING_CONTROL = auto()
51
- COMPETITION = auto()
52
- CONFIGURATION = auto()
53
- CALCULATION = auto()
54
- EVENT_HANDLING = auto()
55
- OTHER = auto()
56
-
57
- SimulationBehaviorFunc = Callable[..., Any]
58
-
59
- class VexFunctionSignature:
60
- """Represents the signature of a VEX function"""
61
-
62
- def __init__(self,
63
- name: str,
64
- return_type: VexType = VOID,
65
- parameters: List[Union[VexFunctionParameter, Tuple[str, str, Optional[Any]]]] = None,
66
- description: str = "",
67
- category: SimulationCategory = SimulationCategory.OTHER,
68
- simulation_behavior: Optional[SimulationBehaviorFunc] = None,
69
- python_name: Optional[str] = None,
70
- cpp_name: Optional[str] = None,
71
- object_type: Optional[VexType] = None,
72
- method_name: Optional[str] = None):
73
- self.name = name
74
- self.return_type = return_type
75
-
76
- # Convert tuple parameters to VexFunctionParameter objects
77
- processed_params = []
78
- if parameters:
79
- for param in parameters:
80
- if isinstance(param, VexFunctionParameter):
81
- processed_params.append(param)
82
- elif isinstance(param, tuple) and len(param) >= 2:
83
- # Extract tuple values
84
- param_name = param[0]
85
- param_type = param[1]
86
- default_value = param[2] if len(param) > 2 else None
87
- processed_params.append(VexFunctionParameter(
88
- name=param_name,
89
- type_=param_type,
90
- default_value=default_value
91
- ))
92
-
93
- self.parameters = processed_params
94
- self.description = description
95
- self.category = category
96
- self.simulation_behavior = simulation_behavior
97
- self.python_name = python_name or name
98
- self.cpp_name = cpp_name or name
99
- self.object_type = object_type # For methods, this is the class type
100
- self.method_name = method_name # For methods, this is the method name
101
-
102
-
103
- # Validate there are no duplicate parameter names
104
- param_names = [param.name for param in self.parameters]
105
- if len(param_names) != len(set(param_names)):
106
- raise ValueError(f"Duplicate parameter names in function {name}")
107
-
108
- # Ensure optional parameters come after required parameters
109
- has_optional = False
110
- for param in self.parameters:
111
- if param.is_optional:
112
- has_optional = True
113
- elif has_optional:
114
- raise ValueError(f"Required parameter after optional parameter in function {name}")
115
-
116
- def __str__(self) -> str:
117
- params_str = ", ".join(str(param) for param in self.parameters)
118
- return f"{self.return_type} {self.name}({params_str})"
119
-
120
- def validate_arguments(self,
121
- args: List[Any],
122
- kwargs: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
123
- """Validate function arguments against this signature"""
124
- # Check if we have too many positional arguments
125
- if len(args) > len(self.parameters):
126
- return False, f"Too many positional arguments for {self.name}"
127
-
128
- # Check if we have unknown keyword arguments
129
- param_names = {param.name for param in self.parameters}
130
- for kwarg_name in kwargs:
131
- if kwarg_name not in param_names:
132
- return False, f"Unknown keyword argument '{kwarg_name}' for {self.name}"
133
-
134
- # Check if we have the required number of arguments
135
- required_params = [p for p in self.parameters if not p.is_optional]
136
- if len(args) + len(kwargs) < len(required_params):
137
- return False, f"Missing required arguments for {self.name}"
138
-
139
- # Check if we have duplicate arguments
140
- args_used = min(len(args), len(self.parameters))
141
- for i in range(args_used):
142
- param_name = self.parameters[i].name
143
- if param_name in kwargs:
144
- return False, f"Duplicate argument '{param_name}' for {self.name}"
145
-
146
- # Type checking for arguments
147
- from ..types.type_checker import type_checker
148
- from ..types.enums import EnumType
149
-
150
- # Check positional arguments
151
- for i, arg in enumerate(args):
152
- if i >= len(self.parameters):
153
- break
154
-
155
- param = self.parameters[i]
156
- expected_type = param.type
157
-
158
- # Handle string literals for enum types
159
- if isinstance(expected_type, EnumType) and isinstance(arg, str):
160
- if arg not in expected_type.values:
161
- return False, f"Invalid enum value '{arg}' for parameter '{param.name}' in {self.name}"
162
- continue
163
-
164
- # Handle other types
165
- if hasattr(arg, 'get_type'):
166
- arg_type = arg.get_type()
167
- if arg_type and not type_checker.is_compatible(arg_type, expected_type):
168
- return False, f"Type mismatch for parameter '{param.name}' in {self.name}: expected {expected_type}, got {arg_type}"
169
-
170
- # Check keyword arguments
171
- for kwarg_name, kwarg_value in kwargs.items():
172
- # Find the parameter
173
- param = next((p for p in self.parameters if p.name == kwarg_name), None)
174
- if not param:
175
- continue # Already checked for unknown kwargs above
176
-
177
- expected_type = param.type
178
-
179
- # Handle string literals for enum types
180
- if isinstance(expected_type, EnumType) and isinstance(kwarg_value, str):
181
- if kwarg_value not in expected_type.values:
182
- return False, f"Invalid enum value '{kwarg_value}' for parameter '{param.name}' in {self.name}"
183
- continue
184
-
185
- # Handle other types
186
- if hasattr(kwarg_value, 'get_type'):
187
- kwarg_type = kwarg_value.get_type()
188
- if kwarg_type and not type_checker.is_compatible(kwarg_type, expected_type):
189
- return False, f"Type mismatch for parameter '{param.name}' in {self.name}: expected {expected_type}, got {kwarg_type}"
190
-
191
- return True, None
1
+ from typing import Optional, List, Dict, Any, Union, Callable, Tuple
2
+ from enum import Enum, auto
3
+ from ..types.base import VexType, VOID, ANY
4
+ from .categories import VexCategory, BehaviorType, SubCategory
5
+
6
+ class ParameterMode(Enum):
7
+ """Parameter passing modes"""
8
+ VALUE = auto() # Pass by value
9
+ REFERENCE = auto() # Pass by reference
10
+ OUTPUT = auto() # Output parameter
11
+
12
+ class VexFunctionParameter:
13
+ """Represents a parameter in a VEX function signature"""
14
+
15
+ def __init__(self,
16
+ name: str,
17
+ type_: VexType,
18
+ default_value: Optional[Any] = None,
19
+ mode: ParameterMode = ParameterMode.VALUE,
20
+ description: str = ""):
21
+ self.name = name
22
+ self.type = type_
23
+ self.default_value = default_value
24
+ self.mode = mode
25
+ self.description = description
26
+ self.is_optional = default_value is not None
27
+
28
+ @property
29
+ def optional(self) -> bool:
30
+ """Alias for is_optional for compatibility."""
31
+ return self.is_optional
32
+
33
+ def __str__(self) -> str:
34
+ mode_str = ""
35
+ if self.mode == ParameterMode.REFERENCE:
36
+ mode_str = "&"
37
+ elif self.mode == ParameterMode.OUTPUT:
38
+ mode_str = "*"
39
+
40
+ default_str = ""
41
+ if self.is_optional:
42
+ default_str = f" = {self.default_value}"
43
+
44
+ return f"{self.type}{mode_str} {self.name}{default_str}"
45
+
46
+ # For backward compatibility
47
+ class SimulationCategory(Enum):
48
+ """Categories for simulation behavior (deprecated, use VexCategory and BehaviorType instead)"""
49
+ MOTOR_CONTROL = auto()
50
+ SENSOR_READING = auto()
51
+ DISPLAY_OUTPUT = auto()
52
+ TIMING_CONTROL = auto()
53
+ COMPETITION = auto()
54
+ CONFIGURATION = auto()
55
+ CALCULATION = auto()
56
+ EVENT_HANDLING = auto()
57
+ OTHER = auto()
58
+
59
+ SimulationBehaviorFunc = Callable[..., Any]
60
+
61
+ class VexFunctionSignature:
62
+ """Represents the signature of a VEX function"""
63
+
64
+ def __init__(self,
65
+ name: str,
66
+ return_type: VexType = VOID,
67
+ parameters: List[Union[VexFunctionParameter, Tuple[str, str, Optional[Any]]]] = None,
68
+ description: str = "",
69
+ category: Union[VexCategory, SimulationCategory] = None,
70
+ behavior: BehaviorType = None,
71
+ subcategory: Optional[SubCategory] = None,
72
+ simulation_behavior: Optional[SimulationBehaviorFunc] = None,
73
+ python_name: Optional[str] = None,
74
+ cpp_name: Optional[str] = None,
75
+ object_type: Optional[VexType] = None,
76
+ method_name: Optional[str] = None):
77
+ self.name = name
78
+ self.return_type = return_type
79
+
80
+ # Convert tuple parameters to VexFunctionParameter objects
81
+ processed_params = []
82
+ if parameters:
83
+ for param in parameters:
84
+ if isinstance(param, VexFunctionParameter):
85
+ processed_params.append(param)
86
+ elif isinstance(param, tuple) and len(param) >= 2:
87
+ # Extract tuple values
88
+ param_name = param[0]
89
+ param_type = param[1]
90
+ default_value = param[2] if len(param) > 2 else None
91
+ processed_params.append(VexFunctionParameter(
92
+ name=param_name,
93
+ type_=param_type,
94
+ default_value=default_value
95
+ ))
96
+
97
+ self.parameters = processed_params
98
+ self.description = description
99
+
100
+ # Handle category and behavior
101
+ from .categories import categorizer
102
+
103
+ # For backward compatibility with SimulationCategory
104
+ if isinstance(category, SimulationCategory):
105
+ # Convert SimulationCategory to BehaviorType
106
+ sim_cat_name = category.name
107
+ self._simulation_category = category # Store original for backward compatibility
108
+
109
+ # Determine category and behavior from function name and description
110
+ self.category, self.behavior, self.subcategory = categorizer.categorize_function(
111
+ name, description
112
+ )
113
+
114
+ # Override behavior based on simulation category mapping
115
+ if sim_cat_name in categorizer.simulation_to_behavior:
116
+ self.behavior = categorizer.simulation_to_behavior[sim_cat_name]
117
+ else:
118
+ # Use provided category and behavior or determine from function name
119
+ if category is None or behavior is None:
120
+ self.category, self.behavior, self.subcategory = categorizer.categorize_function(
121
+ name, description
122
+ )
123
+ if category is not None:
124
+ self.category = category
125
+ if behavior is not None:
126
+ self.behavior = behavior
127
+ if subcategory is not None:
128
+ self.subcategory = subcategory
129
+ else:
130
+ self.category = category
131
+ self.behavior = behavior
132
+ self.subcategory = subcategory
133
+
134
+ # For backward compatibility, map to SimulationCategory
135
+ if self.behavior == BehaviorType.CONTROL and self.category == VexCategory.MOTOR:
136
+ self._simulation_category = SimulationCategory.MOTOR_CONTROL
137
+ elif self.behavior == BehaviorType.READ and self.category == VexCategory.SENSOR:
138
+ self._simulation_category = SimulationCategory.SENSOR_READING
139
+ elif self.behavior == BehaviorType.OUTPUT and self.category == VexCategory.DISPLAY:
140
+ self._simulation_category = SimulationCategory.DISPLAY_OUTPUT
141
+ elif self.behavior == BehaviorType.CONTROL and self.category == VexCategory.TIMING:
142
+ self._simulation_category = SimulationCategory.TIMING_CONTROL
143
+ elif self.category == VexCategory.COMPETITION:
144
+ self._simulation_category = SimulationCategory.COMPETITION
145
+ elif self.behavior == BehaviorType.CONFIG:
146
+ self._simulation_category = SimulationCategory.CONFIGURATION
147
+ elif self.behavior == BehaviorType.EVENT:
148
+ self._simulation_category = SimulationCategory.EVENT_HANDLING
149
+ else:
150
+ self._simulation_category = SimulationCategory.OTHER
151
+
152
+ self.simulation_behavior = simulation_behavior
153
+ self.python_name = python_name or name
154
+ self.cpp_name = cpp_name or name
155
+ self.object_type = object_type # For methods, this is the class type
156
+ self.method_name = method_name # For methods, this is the method name
157
+
158
+ # Validate there are no duplicate parameter names
159
+ param_names = [param.name for param in self.parameters]
160
+ if len(param_names) != len(set(param_names)):
161
+ raise ValueError(f"Duplicate parameter names in function {name}")
162
+
163
+ # Ensure optional parameters come after required parameters
164
+ has_optional = False
165
+ for param in self.parameters:
166
+ if param.is_optional:
167
+ has_optional = True
168
+ elif has_optional:
169
+ raise ValueError(f"Required parameter after optional parameter in function {name}")
170
+
171
+ @property
172
+ def simulation_category(self) -> SimulationCategory:
173
+ """Get the simulation category (for backward compatibility)"""
174
+ if hasattr(self, '_simulation_category'):
175
+ return self._simulation_category
176
+ return SimulationCategory.OTHER
177
+
178
+ # Alias for backward compatibility
179
+ @property
180
+ def category(self) -> Union[VexCategory, SimulationCategory]:
181
+ """Get the category (for backward compatibility)"""
182
+ return self.simulation_category
183
+
184
+ @category.setter
185
+ def category(self, value: Union[VexCategory, SimulationCategory]):
186
+ """Set the category"""
187
+ if isinstance(value, SimulationCategory):
188
+ # For backward compatibility
189
+ self._simulation_category = value
190
+ else:
191
+ # New category system
192
+ self.vex_category = value
193
+
194
+ def __str__(self) -> str:
195
+ params_str = ", ".join(str(param) for param in self.parameters)
196
+ return f"{self.return_type} {self.name}({params_str})"
197
+
198
+ def validate_arguments(self,
199
+ args: List[Any],
200
+ kwargs: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
201
+ """Validate function arguments against this signature"""
202
+ # Check if we have too many positional arguments
203
+ if len(args) > len(self.parameters):
204
+ return False, f"Too many positional arguments for {self.name}"
205
+
206
+ # Check if we have unknown keyword arguments
207
+ param_names = {param.name for param in self.parameters}
208
+ for kwarg_name in kwargs:
209
+ if kwarg_name not in param_names:
210
+ return False, f"Unknown keyword argument '{kwarg_name}' for {self.name}"
211
+
212
+ # Check if we have the required number of arguments
213
+ required_params = [p for p in self.parameters if not p.is_optional]
214
+ if len(args) + len(kwargs) < len(required_params):
215
+ return False, f"Missing required arguments for {self.name}"
216
+
217
+ # Check if we have duplicate arguments
218
+ args_used = min(len(args), len(self.parameters))
219
+ for i in range(args_used):
220
+ param_name = self.parameters[i].name
221
+ if param_name in kwargs:
222
+ return False, f"Duplicate argument '{param_name}' for {self.name}"
223
+
224
+ # Type checking for arguments
225
+ from ..types.type_checker import type_checker
226
+ from ..types.enums import EnumType
227
+
228
+ # Check positional arguments
229
+ for i, arg in enumerate(args):
230
+ if i >= len(self.parameters):
231
+ break
232
+
233
+ param = self.parameters[i]
234
+ expected_type = param.type
235
+
236
+ # Handle string literals for enum types
237
+ if isinstance(expected_type, EnumType) and isinstance(arg, str):
238
+ if arg not in expected_type.values:
239
+ return False, f"Invalid enum value '{arg}' for parameter '{param.name}' in {self.name}"
240
+ continue
241
+
242
+ # Handle other types
243
+ if hasattr(arg, 'get_type'):
244
+ arg_type = arg.get_type()
245
+ if arg_type and not type_checker.is_compatible(arg_type, expected_type):
246
+ return False, f"Type mismatch for parameter '{param.name}' in {self.name}: expected {expected_type}, got {arg_type}"
247
+
248
+ # Check keyword arguments
249
+ for kwarg_name, kwarg_value in kwargs.items():
250
+ # Find the parameter
251
+ param = next((p for p in self.parameters if p.name == kwarg_name), None)
252
+ if not param:
253
+ continue # Already checked for unknown kwargs above
254
+
255
+ expected_type = param.type
256
+
257
+ # Handle string literals for enum types
258
+ if isinstance(expected_type, EnumType) and isinstance(kwarg_value, str):
259
+ if kwarg_value not in expected_type.values:
260
+ return False, f"Invalid enum value '{kwarg_value}' for parameter '{param.name}' in {self.name}"
261
+ continue
262
+
263
+ # Handle other types
264
+ if hasattr(kwarg_value, 'get_type'):
265
+ kwarg_type = kwarg_value.get_type()
266
+ if kwarg_type and not type_checker.is_compatible(kwarg_type, expected_type):
267
+ return False, f"Type mismatch for parameter '{param.name}' in {self.name}: expected {expected_type}, got {kwarg_type}"
268
+
269
+ return True, None
@@ -1,9 +1,9 @@
1
- # vex_ast/registry/simulation_behavior.py
2
- from enum import Enum, auto
3
-
4
- class SimulationBehavior(Enum):
5
- """Categories of simulation behaviors for VEX functions"""
6
- AFFECTS_MOTOR = "AFFECTS_MOTOR"
7
- READS_SENSOR = "READS_SENSOR"
8
- AFFECTS_TIMING = "AFFECTS_TIMING"
1
+ # vex_ast/registry/simulation_behavior.py
2
+ from enum import Enum, auto
3
+
4
+ class SimulationBehavior(Enum):
5
+ """Categories of simulation behaviors for VEX functions"""
6
+ AFFECTS_MOTOR = "AFFECTS_MOTOR"
7
+ READS_SENSOR = "READS_SENSOR"
8
+ AFFECTS_TIMING = "AFFECTS_TIMING"
9
9
  AFFECTS_DISPLAY = "AFFECTS_DISPLAY"
@@ -1,44 +1,44 @@
1
- from typing import Dict, List, Optional, Set, Tuple, Any, Union
2
- from ..types.base import VexType
3
- from ..types.type_checker import type_checker
4
- from .registry import registry, VexFunctionRegistry
5
- from .signature import VexFunctionSignature, VexFunctionParameter
6
-
7
- class FunctionCallValidator:
8
- """Validates function calls against the registry"""
9
-
10
- def __init__(self, registry: VexFunctionRegistry = registry):
11
- self.registry = registry
12
-
13
- def validate_call(self,
14
- function_name: str,
15
- args: List[Any] = None,
16
- kwargs: Dict[str, Any] = None,
17
- language: str = "python") -> Tuple[bool, Optional[str]]:
18
- """Validate a function call"""
19
- args = args or []
20
- kwargs = kwargs or {}
21
- return self.registry.validate_call(function_name, args, kwargs, language)
22
-
23
- def validate_method_call(self,
24
- object_type: Union[VexType, str],
25
- method_name: str,
26
- args: List[Any] = None,
27
- kwargs: Dict[str, Any] = None) -> Tuple[bool, Optional[str]]:
28
- """Validate a method call on an object"""
29
- args = args or []
30
- kwargs = kwargs or {}
31
- return self.registry.validate_method_call(object_type, method_name, args, kwargs)
32
-
33
- def validate_ast_function_call(self, function_call_node: Any) -> Tuple[bool, Optional[str]]:
34
- """Validate a function call AST node"""
35
- # This would need to be implemented based on the actual AST node structure
36
- # For now, just a placeholder showing the interface
37
- function_name = function_call_node.function.name
38
- args = [arg.value for arg in function_call_node.args]
39
- kwargs = {kw.name: kw.value for kw in function_call_node.keywords}
40
-
41
- return self.validate_call(function_name, args, kwargs)
42
-
43
- # Singleton instance
1
+ from typing import Dict, List, Optional, Set, Tuple, Any, Union
2
+ from ..types.base import VexType
3
+ from ..types.type_checker import type_checker
4
+ from .registry import registry, VexFunctionRegistry
5
+ from .signature import VexFunctionSignature, VexFunctionParameter
6
+
7
+ class FunctionCallValidator:
8
+ """Validates function calls against the registry"""
9
+
10
+ def __init__(self, registry: VexFunctionRegistry = registry):
11
+ self.registry = registry
12
+
13
+ def validate_call(self,
14
+ function_name: str,
15
+ args: List[Any] = None,
16
+ kwargs: Dict[str, Any] = None,
17
+ language: str = "python") -> Tuple[bool, Optional[str]]:
18
+ """Validate a function call"""
19
+ args = args or []
20
+ kwargs = kwargs or {}
21
+ return self.registry.validate_call(function_name, args, kwargs, language)
22
+
23
+ def validate_method_call(self,
24
+ object_type: Union[VexType, str],
25
+ method_name: str,
26
+ args: List[Any] = None,
27
+ kwargs: Dict[str, Any] = None) -> Tuple[bool, Optional[str]]:
28
+ """Validate a method call on an object"""
29
+ args = args or []
30
+ kwargs = kwargs or {}
31
+ return self.registry.validate_method_call(object_type, method_name, args, kwargs)
32
+
33
+ def validate_ast_function_call(self, function_call_node: Any) -> Tuple[bool, Optional[str]]:
34
+ """Validate a function call AST node"""
35
+ # This would need to be implemented based on the actual AST node structure
36
+ # For now, just a placeholder showing the interface
37
+ function_name = function_call_node.function.name
38
+ args = [arg.value for arg in function_call_node.args]
39
+ kwargs = {kw.name: kw.value for kw in function_call_node.keywords}
40
+
41
+ return self.validate_call(function_name, args, kwargs)
42
+
43
+ # Singleton instance
44
44
  validator = FunctionCallValidator()