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,78 +1,78 @@
1
- from typing import Dict, Set, List, Optional, Tuple
2
-
3
- class LanguageMapper:
4
- """Utility for mapping between Python and C++ function names"""
5
-
6
- def __init__(self):
7
- self.python_to_cpp: Dict[str, str] = {}
8
- self.cpp_to_python: Dict[str, str] = {}
9
-
10
- # Common pattern transformations
11
- # Python: snake_case, C++: camelCase or PascalCase
12
- self.python_patterns = {
13
- "set_": "set",
14
- "get_": "get",
15
- "is_": "is",
16
- "has_": "has",
17
- }
18
-
19
- def register_mapping(self, python_name: str, cpp_name: str) -> None:
20
- """Register a mapping between Python and C++ function names"""
21
- self.python_to_cpp[python_name] = cpp_name
22
- self.cpp_to_python[cpp_name] = python_name
23
-
24
- def get_cpp_name(self, python_name: str) -> Optional[str]:
25
- """Get the C++ name for a Python function name"""
26
- # Direct lookup
27
- if python_name in self.python_to_cpp:
28
- return self.python_to_cpp[python_name]
29
-
30
- # Try pattern matching
31
- for py_pattern, cpp_pattern in self.python_patterns.items():
32
- if python_name.startswith(py_pattern):
33
- # Convert snake_case to camelCase
34
- rest = python_name[len(py_pattern):]
35
- parts = rest.split('_')
36
- camel_case = parts[0] + ''.join(part.capitalize() for part in parts[1:])
37
- return cpp_pattern + camel_case.capitalize()
38
-
39
- # Default: convert snake_case to camelCase
40
- parts = python_name.split('_')
41
- return parts[0] + ''.join(part.capitalize() for part in parts[1:])
42
-
43
- def get_python_name(self, cpp_name: str) -> Optional[str]:
44
- """Get the Python name for a C++ function name"""
45
- # Direct lookup
46
- if cpp_name in self.cpp_to_python:
47
- return self.cpp_to_python[cpp_name]
48
-
49
- # Try to convert camelCase to snake_case
50
- result = ''
51
- for char in cpp_name:
52
- if char.isupper() and result:
53
- result += '_'
54
- result += char.lower()
55
- return result
56
-
57
- # Singleton instance
58
- language_mapper = LanguageMapper()
59
-
60
- # Register common VEX function mappings
61
- common_mappings = {
62
- # Motor functions
63
- "spin": "spin",
64
- "stop": "stop",
65
- "set_velocity": "setVelocity",
66
- "set_stopping": "setStopping",
67
-
68
- # Drivetrain functions
69
- "drive": "drive",
70
- "turn": "turn",
71
- "drive_for": "driveFor",
72
- "turn_for": "turnFor",
73
-
74
- # Add more mappings as needed
75
- }
76
-
77
- for py_name, cpp_name in common_mappings.items():
1
+ from typing import Dict, Set, List, Optional, Tuple
2
+
3
+ class LanguageMapper:
4
+ """Utility for mapping between Python and C++ function names"""
5
+
6
+ def __init__(self):
7
+ self.python_to_cpp: Dict[str, str] = {}
8
+ self.cpp_to_python: Dict[str, str] = {}
9
+
10
+ # Common pattern transformations
11
+ # Python: snake_case, C++: camelCase or PascalCase
12
+ self.python_patterns = {
13
+ "set_": "set",
14
+ "get_": "get",
15
+ "is_": "is",
16
+ "has_": "has",
17
+ }
18
+
19
+ def register_mapping(self, python_name: str, cpp_name: str) -> None:
20
+ """Register a mapping between Python and C++ function names"""
21
+ self.python_to_cpp[python_name] = cpp_name
22
+ self.cpp_to_python[cpp_name] = python_name
23
+
24
+ def get_cpp_name(self, python_name: str) -> Optional[str]:
25
+ """Get the C++ name for a Python function name"""
26
+ # Direct lookup
27
+ if python_name in self.python_to_cpp:
28
+ return self.python_to_cpp[python_name]
29
+
30
+ # Try pattern matching
31
+ for py_pattern, cpp_pattern in self.python_patterns.items():
32
+ if python_name.startswith(py_pattern):
33
+ # Convert snake_case to camelCase
34
+ rest = python_name[len(py_pattern):]
35
+ parts = rest.split('_')
36
+ camel_case = parts[0] + ''.join(part.capitalize() for part in parts[1:])
37
+ return cpp_pattern + camel_case.capitalize()
38
+
39
+ # Default: convert snake_case to camelCase
40
+ parts = python_name.split('_')
41
+ return parts[0] + ''.join(part.capitalize() for part in parts[1:])
42
+
43
+ def get_python_name(self, cpp_name: str) -> Optional[str]:
44
+ """Get the Python name for a C++ function name"""
45
+ # Direct lookup
46
+ if cpp_name in self.cpp_to_python:
47
+ return self.cpp_to_python[cpp_name]
48
+
49
+ # Try to convert camelCase to snake_case
50
+ result = ''
51
+ for char in cpp_name:
52
+ if char.isupper() and result:
53
+ result += '_'
54
+ result += char.lower()
55
+ return result
56
+
57
+ # Singleton instance
58
+ language_mapper = LanguageMapper()
59
+
60
+ # Register common VEX function mappings
61
+ common_mappings = {
62
+ # Motor functions
63
+ "spin": "spin",
64
+ "stop": "stop",
65
+ "set_velocity": "setVelocity",
66
+ "set_stopping": "setStopping",
67
+
68
+ # Drivetrain functions
69
+ "drive": "drive",
70
+ "turn": "turn",
71
+ "drive_for": "driveFor",
72
+ "turn_for": "turnFor",
73
+
74
+ # Add more mappings as needed
75
+ }
76
+
77
+ for py_name, cpp_name in common_mappings.items():
78
78
  language_mapper.register_mapping(py_name, cpp_name)
@@ -1,153 +1,164 @@
1
- from typing import Dict, List, Optional, Set, Tuple, Any, Union
2
- from enum import Enum
3
- from .signature import VexFunctionSignature, VexFunctionParameter, SimulationCategory
4
- from ..types.base import VexType
5
- from .categories import FunctionCategory, SubCategory, categorizer
6
- from .language_map import language_mapper
7
- from .simulation_behavior import SimulationBehavior
8
-
9
- class VexFunctionRegistry:
10
- """Registry for storing and retrieving VEX function signatures"""
11
-
12
- _instance = None
13
-
14
- @classmethod
15
- def register(cls, signature: VexFunctionSignature) -> None:
16
- """Static method to register a function signature in the registry"""
17
- instance = cls()
18
- instance.register_function(signature)
19
-
20
- def __new__(cls):
21
- if cls._instance is None:
22
- cls._instance = super(VexFunctionRegistry, cls).__new__(cls)
23
- cls._instance._initialize()
24
- return cls._instance
25
-
26
- def _initialize(self) -> None:
27
- """Initialize the registry"""
28
- self.functions: Dict[str, VexFunctionSignature] = {}
29
- self.functions_by_category: Dict[FunctionCategory, List[VexFunctionSignature]] = {}
30
- self.functions_by_subcategory: Dict[SubCategory, List[VexFunctionSignature]] = {}
31
- self.functions_by_simulation: Dict[SimulationCategory, List[VexFunctionSignature]] = {}
32
- self.method_map: Dict[Tuple[str, str], VexFunctionSignature] = {} # (object_type, method_name) -> signature
33
-
34
- # Initialize category dictionaries
35
- for category in FunctionCategory:
36
- self.functions_by_category[category] = []
37
-
38
- for subcategory in SubCategory:
39
- self.functions_by_subcategory[subcategory] = []
40
-
41
- for sim_category in SimulationCategory:
42
- self.functions_by_simulation[sim_category] = []
43
-
44
- def register_function(self, signature: VexFunctionSignature) -> None:
45
- """Register a function signature in the registry"""
46
- # Register by name
47
- self.functions[signature.name] = signature
48
-
49
- # Register Python and C++ name variations
50
- if signature.python_name and signature.python_name != signature.name:
51
- self.functions[signature.python_name] = signature
52
-
53
- if signature.cpp_name and signature.cpp_name != signature.name:
54
- self.functions[signature.cpp_name] = signature
55
-
56
- # Register by simulation category
57
- self.functions_by_simulation[signature.category].append(signature)
58
-
59
- # Categorize function
60
- category, subcategory = categorizer.categorize_function(
61
- signature.name, signature.description
62
- )
63
-
64
- # Register by category
65
- self.functions_by_category[category].append(signature)
66
-
67
- # Register by subcategory if available
68
- if subcategory:
69
- self.functions_by_subcategory[subcategory].append(signature)
70
-
71
- # Register as method if applicable
72
- if signature.object_type and signature.method_name:
73
- key = (signature.object_type.name, signature.method_name)
74
- self.method_map[key] = signature
75
-
76
- def get_function(self,
77
- name: str,
78
- language: str = "python") -> Optional[VexFunctionSignature]:
79
- """Get a function signature by name"""
80
- # Try direct lookup
81
- if name in self.functions:
82
- return self.functions[name]
83
-
84
- # Try language-specific lookup
85
- if language == "cpp":
86
- python_name = language_mapper.get_python_name(name)
87
- if python_name and python_name in self.functions:
88
- return self.functions[python_name]
89
- elif language == "python":
90
- cpp_name = language_mapper.get_cpp_name(name)
91
- if cpp_name and cpp_name in self.functions:
92
- return self.functions[cpp_name]
93
-
94
- return None
95
-
96
- def get_method(self,
97
- object_type: Union[VexType, str],
98
- method_name: str) -> Optional[VexFunctionSignature]:
99
- """Get a method signature for an object type and method name"""
100
- type_name = object_type.name if hasattr(object_type, 'name') else str(object_type)
101
- key = (type_name, method_name)
102
- return self.method_map.get(key)
103
-
104
- def get_functions_by_category(self, category: FunctionCategory) -> List[VexFunctionSignature]:
105
- """Get all functions in a category"""
106
- return self.functions_by_category.get(category, [])
107
-
108
- def get_functions_by_subcategory(self, subcategory: SubCategory) -> List[VexFunctionSignature]:
109
- """Get all functions in a subcategory"""
110
- return self.functions_by_subcategory.get(subcategory, [])
111
-
112
- def get_functions_by_simulation(self,
113
- sim_category: SimulationCategory) -> List[VexFunctionSignature]:
114
- """Get all functions with a specific simulation category"""
115
- return self.functions_by_simulation.get(sim_category, [])
116
-
117
- def validate_call(self,
118
- function_name: str,
119
- args: List[Any],
120
- kwargs: Dict[str, Any],
121
- language: str = "python") -> Tuple[bool, Optional[str]]:
122
- """Validate a function call"""
123
- # Get the function signature
124
- signature = self.get_function(function_name, language)
125
- if not signature:
126
- return False, f"Unknown function: {function_name}"
127
-
128
- # Validate arguments
129
- return signature.validate_arguments(args, kwargs)
130
-
131
- def validate_method_call(self,
132
- object_type: Union[VexType, str],
133
- method_name: str,
134
- args: List[Any],
135
- kwargs: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
136
- """Validate a method call on an object"""
137
- # Get the method signature
138
- signature = self.get_method(object_type, method_name)
139
- if not signature:
140
- type_name = object_type.name if hasattr(object_type, 'name') else str(object_type)
141
- return False, f"Unknown method {method_name} for type {type_name}"
142
-
143
- # Validate arguments
144
- return signature.validate_arguments(args, kwargs)
145
-
146
- def get_all_functions(self) -> List[VexFunctionSignature]:
147
- """Get all registered functions"""
148
- # Use set to remove duplicates since a function can be registered multiple times
149
- # with different names
150
- return list(set(self.functions.values()))
151
-
152
- # Singleton instance
153
- registry = VexFunctionRegistry()
1
+ from typing import Dict, List, Optional, Set, Tuple, Any, Union
2
+ from enum import Enum
3
+ from .signature import VexFunctionSignature, VexFunctionParameter, SimulationCategory
4
+ from ..types.base import VexType
5
+ from .categories import VexCategory, BehaviorType, SubCategory, categorizer
6
+ from .language_map import language_mapper
7
+ from .simulation_behavior import SimulationBehavior
8
+
9
+ class VexFunctionRegistry:
10
+ """Registry for storing and retrieving VEX function signatures"""
11
+
12
+ _instance = None
13
+
14
+ @classmethod
15
+ def register(cls, signature: VexFunctionSignature) -> None:
16
+ """Static method to register a function signature in the registry"""
17
+ instance = cls()
18
+ instance.register_function(signature)
19
+
20
+ def __new__(cls):
21
+ if cls._instance is None:
22
+ cls._instance = super(VexFunctionRegistry, cls).__new__(cls)
23
+ cls._instance._initialize()
24
+ return cls._instance
25
+
26
+ def _initialize(self) -> None:
27
+ """Initialize the registry"""
28
+ self.functions: Dict[str, VexFunctionSignature] = {}
29
+
30
+ # New categorization system
31
+ self.functions_by_category: Dict[VexCategory, List[VexFunctionSignature]] = {}
32
+ self.functions_by_behavior: Dict[BehaviorType, List[VexFunctionSignature]] = {}
33
+ self.functions_by_subcategory: Dict[SubCategory, List[VexFunctionSignature]] = {}
34
+
35
+ # For backward compatibility
36
+ self.functions_by_simulation: Dict[SimulationCategory, List[VexFunctionSignature]] = {}
37
+
38
+ self.method_map: Dict[Tuple[str, str], VexFunctionSignature] = {} # (object_type, method_name) -> signature
39
+
40
+ # Initialize category dictionaries
41
+ for category in VexCategory:
42
+ self.functions_by_category[category] = []
43
+
44
+ for behavior in BehaviorType:
45
+ self.functions_by_behavior[behavior] = []
46
+
47
+ for subcategory in SubCategory:
48
+ self.functions_by_subcategory[subcategory] = []
49
+
50
+ for sim_category in SimulationCategory:
51
+ self.functions_by_simulation[sim_category] = []
52
+
53
+ def register_function(self, signature: VexFunctionSignature) -> None:
54
+ """Register a function signature in the registry"""
55
+ # Register by name
56
+ self.functions[signature.name] = signature
57
+
58
+ # Register Python and C++ name variations
59
+ if signature.python_name and signature.python_name != signature.name:
60
+ self.functions[signature.python_name] = signature
61
+
62
+ if signature.cpp_name and signature.cpp_name != signature.name:
63
+ self.functions[signature.cpp_name] = signature
64
+
65
+ # Register by simulation category (for backward compatibility)
66
+ self.functions_by_simulation[signature.simulation_category].append(signature)
67
+
68
+ # Register by new category system
69
+ if hasattr(signature, 'vex_category'):
70
+ self.functions_by_category[signature.vex_category].append(signature)
71
+
72
+ if hasattr(signature, 'behavior'):
73
+ self.functions_by_behavior[signature.behavior].append(signature)
74
+
75
+ if hasattr(signature, 'subcategory') and signature.subcategory:
76
+ self.functions_by_subcategory[signature.subcategory].append(signature)
77
+
78
+ # Register as method if applicable
79
+ if signature.object_type and signature.method_name:
80
+ key = (signature.object_type.name, signature.method_name)
81
+ self.method_map[key] = signature
82
+
83
+ def get_function(self,
84
+ name: str,
85
+ language: str = "python") -> Optional[VexFunctionSignature]:
86
+ """Get a function signature by name"""
87
+ # Try direct lookup
88
+ if name in self.functions:
89
+ return self.functions[name]
90
+
91
+ # Try language-specific lookup
92
+ if language == "cpp":
93
+ python_name = language_mapper.get_python_name(name)
94
+ if python_name and python_name in self.functions:
95
+ return self.functions[python_name]
96
+ elif language == "python":
97
+ cpp_name = language_mapper.get_cpp_name(name)
98
+ if cpp_name and cpp_name in self.functions:
99
+ return self.functions[cpp_name]
100
+
101
+ return None
102
+
103
+ def get_method(self,
104
+ object_type: Union[VexType, str],
105
+ method_name: str) -> Optional[VexFunctionSignature]:
106
+ """Get a method signature for an object type and method name"""
107
+ type_name = object_type.name if hasattr(object_type, 'name') else str(object_type)
108
+ key = (type_name, method_name)
109
+ return self.method_map.get(key)
110
+
111
+ def get_functions_by_category(self, category: VexCategory) -> List[VexFunctionSignature]:
112
+ """Get all functions in a category"""
113
+ return self.functions_by_category.get(category, [])
114
+
115
+ def get_functions_by_behavior(self, behavior: BehaviorType) -> List[VexFunctionSignature]:
116
+ """Get all functions with a specific behavior type"""
117
+ return self.functions_by_behavior.get(behavior, [])
118
+
119
+ def get_functions_by_subcategory(self, subcategory: SubCategory) -> List[VexFunctionSignature]:
120
+ """Get all functions in a subcategory"""
121
+ return self.functions_by_subcategory.get(subcategory, [])
122
+
123
+ def get_functions_by_simulation(self,
124
+ sim_category: SimulationCategory) -> List[VexFunctionSignature]:
125
+ """Get all functions with a specific simulation category (for backward compatibility)"""
126
+ return self.functions_by_simulation.get(sim_category, [])
127
+
128
+ def validate_call(self,
129
+ function_name: str,
130
+ args: List[Any],
131
+ kwargs: Dict[str, Any],
132
+ language: str = "python") -> Tuple[bool, Optional[str]]:
133
+ """Validate a function call"""
134
+ # Get the function signature
135
+ signature = self.get_function(function_name, language)
136
+ if not signature:
137
+ return False, f"Unknown function: {function_name}"
138
+
139
+ # Validate arguments
140
+ return signature.validate_arguments(args, kwargs)
141
+
142
+ def validate_method_call(self,
143
+ object_type: Union[VexType, str],
144
+ method_name: str,
145
+ args: List[Any],
146
+ kwargs: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
147
+ """Validate a method call on an object"""
148
+ # Get the method signature
149
+ signature = self.get_method(object_type, method_name)
150
+ if not signature:
151
+ type_name = object_type.name if hasattr(object_type, 'name') else str(object_type)
152
+ return False, f"Unknown method {method_name} for type {type_name}"
153
+
154
+ # Validate arguments
155
+ return signature.validate_arguments(args, kwargs)
156
+
157
+ def get_all_functions(self) -> List[VexFunctionSignature]:
158
+ """Get all registered functions"""
159
+ # Use set to remove duplicates since a function can be registered multiple times
160
+ # with different names
161
+ return list(set(self.functions.values()))
162
+
163
+ # Singleton instance
164
+ registry = VexFunctionRegistry()