vex-ast 0.1.0__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 (41) hide show
  1. vex_ast/__init__.py +65 -0
  2. vex_ast/ast/__init__.py +75 -0
  3. vex_ast/ast/core.py +71 -0
  4. vex_ast/ast/expressions.py +233 -0
  5. vex_ast/ast/interfaces.py +192 -0
  6. vex_ast/ast/literals.py +80 -0
  7. vex_ast/ast/navigator.py +213 -0
  8. vex_ast/ast/operators.py +136 -0
  9. vex_ast/ast/statements.py +351 -0
  10. vex_ast/ast/validators.py +114 -0
  11. vex_ast/ast/vex_nodes.py +241 -0
  12. vex_ast/parser/__init__.py +0 -0
  13. vex_ast/parser/factory.py +179 -0
  14. vex_ast/parser/interfaces.py +35 -0
  15. vex_ast/parser/python_parser.py +725 -0
  16. vex_ast/parser/strategies.py +0 -0
  17. vex_ast/registry/__init__.py +51 -0
  18. vex_ast/registry/api.py +155 -0
  19. vex_ast/registry/categories.py +136 -0
  20. vex_ast/registry/language_map.py +78 -0
  21. vex_ast/registry/registry.py +153 -0
  22. vex_ast/registry/signature.py +143 -0
  23. vex_ast/registry/simulation_behavior.py +9 -0
  24. vex_ast/registry/validation.py +44 -0
  25. vex_ast/serialization/__init__.py +37 -0
  26. vex_ast/serialization/json_deserializer.py +264 -0
  27. vex_ast/serialization/json_serializer.py +148 -0
  28. vex_ast/serialization/schema.py +471 -0
  29. vex_ast/utils/__init__.py +0 -0
  30. vex_ast/utils/errors.py +112 -0
  31. vex_ast/utils/source_location.py +39 -0
  32. vex_ast/utils/type_definitions.py +0 -0
  33. vex_ast/visitors/__init__.py +0 -0
  34. vex_ast/visitors/analyzer.py +103 -0
  35. vex_ast/visitors/base.py +130 -0
  36. vex_ast/visitors/printer.py +145 -0
  37. vex_ast/visitors/transformer.py +0 -0
  38. vex_ast-0.1.0.dist-info/METADATA +176 -0
  39. vex_ast-0.1.0.dist-info/RECORD +41 -0
  40. vex_ast-0.1.0.dist-info/WHEEL +5 -0
  41. vex_ast-0.1.0.dist-info/top_level.txt +1 -0
File without changes
@@ -0,0 +1,51 @@
1
+ """Registry package for VEX AST functions and types."""
2
+
3
+ from .registry import registry, VexFunctionRegistry
4
+ from .signature import (
5
+ VexFunctionSignature,
6
+ VexFunctionParameter,
7
+ ParameterMode,
8
+ SimulationCategory
9
+ )
10
+ from .categories import (
11
+ FunctionCategory,
12
+ SubCategory,
13
+ categorizer
14
+ )
15
+ from .language_map import language_mapper
16
+ from .validation import validator
17
+ from .simulation_behavior import SimulationBehavior
18
+ from .api import registry_api, RegistryAPI
19
+
20
+ # Initialize registry with default values
21
+ def initialize():
22
+ """Initialize the registry with all VEX functions"""
23
+ from .functions.initialize import initialize_registry
24
+ initialize_registry()
25
+
26
+ __all__ = [
27
+ # Legacy direct access (deprecated)
28
+ 'registry',
29
+ 'VexFunctionRegistry',
30
+
31
+ # Preferred API access
32
+ 'registry_api',
33
+ 'RegistryAPI',
34
+
35
+ # Common types and enums
36
+ 'VexFunctionSignature',
37
+ 'VexFunctionParameter',
38
+ 'ParameterMode',
39
+ 'SimulationCategory',
40
+ 'SimulationBehavior',
41
+ 'FunctionCategory',
42
+ 'SubCategory',
43
+
44
+ # Utility objects
45
+ 'categorizer',
46
+ 'language_mapper',
47
+ 'validator',
48
+
49
+ # Functions
50
+ 'initialize'
51
+ ]
@@ -0,0 +1,155 @@
1
+ """API layer for the VEX function registry.
2
+
3
+ This module provides a clean API for accessing the VEX function registry,
4
+ hiding implementation details and providing a more stable interface.
5
+ """
6
+
7
+ from typing import Dict, List, Optional, Union, Tuple, Any, Set
8
+
9
+ from .registry import registry, VexFunctionRegistry
10
+ from .signature import VexFunctionSignature, SimulationCategory
11
+ from .categories import FunctionCategory, SubCategory
12
+ from ..types.base import VexType
13
+
14
+ class RegistryAPI:
15
+ """API layer for the VEX function registry."""
16
+
17
+ def __init__(self, registry_instance: VexFunctionRegistry = None):
18
+ """Initialize with a registry instance or use the singleton."""
19
+ self._registry = registry_instance or registry
20
+
21
+ def get_function(self, name: str, language: str = "python") -> Optional[VexFunctionSignature]:
22
+ """Get a function signature by name.
23
+
24
+ Args:
25
+ name: The function name
26
+ language: The language to use for name resolution ("python" or "cpp")
27
+
28
+ Returns:
29
+ The function signature if found, None otherwise
30
+ """
31
+ return self._registry.get_function(name, language)
32
+
33
+ def get_method(self, object_type: Union[VexType, str],
34
+ method_name: str) -> Optional[VexFunctionSignature]:
35
+ """Get a method signature for an object type and method name.
36
+
37
+ Args:
38
+ object_type: The object type or type name
39
+ method_name: The method name
40
+
41
+ Returns:
42
+ The method signature if found, None otherwise
43
+ """
44
+ return self._registry.get_method(object_type, method_name)
45
+
46
+ def get_functions_by_category(self, category: FunctionCategory) -> List[VexFunctionSignature]:
47
+ """Get all functions in a category.
48
+
49
+ Args:
50
+ category: The function category
51
+
52
+ Returns:
53
+ List of function signatures in the category
54
+ """
55
+ return self._registry.get_functions_by_category(category)
56
+
57
+ def get_functions_by_subcategory(self, subcategory: SubCategory) -> List[VexFunctionSignature]:
58
+ """Get all functions in a subcategory.
59
+
60
+ Args:
61
+ subcategory: The function subcategory
62
+
63
+ Returns:
64
+ List of function signatures in the subcategory
65
+ """
66
+ return self._registry.get_functions_by_subcategory(subcategory)
67
+
68
+ def get_functions_by_simulation(self,
69
+ sim_category: SimulationCategory) -> List[VexFunctionSignature]:
70
+ """Get all functions with a specific simulation category.
71
+
72
+ Args:
73
+ sim_category: The simulation category
74
+
75
+ Returns:
76
+ List of function signatures with the simulation category
77
+ """
78
+ return self._registry.get_functions_by_simulation(sim_category)
79
+
80
+ def validate_call(self, function_name: str,
81
+ args: List[Any],
82
+ kwargs: Dict[str, Any],
83
+ language: str = "python") -> Tuple[bool, Optional[str]]:
84
+ """Validate a function call.
85
+
86
+ Args:
87
+ function_name: The function name
88
+ args: The positional arguments
89
+ kwargs: The keyword arguments
90
+ language: The language to use for name resolution
91
+
92
+ Returns:
93
+ A tuple of (valid, error_message)
94
+ """
95
+ return self._registry.validate_call(function_name, args, kwargs, language)
96
+
97
+ def validate_method_call(self, object_type: Union[VexType, str],
98
+ method_name: str,
99
+ args: List[Any],
100
+ kwargs: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
101
+ """Validate a method call on an object.
102
+
103
+ Args:
104
+ object_type: The object type or type name
105
+ method_name: The method name
106
+ args: The positional arguments
107
+ kwargs: The keyword arguments
108
+
109
+ Returns:
110
+ A tuple of (valid, error_message)
111
+ """
112
+ return self._registry.validate_method_call(object_type, method_name, args, kwargs)
113
+
114
+ def get_all_functions(self) -> List[VexFunctionSignature]:
115
+ """Get all registered functions.
116
+
117
+ Returns:
118
+ List of all function signatures
119
+ """
120
+ return self._registry.get_all_functions()
121
+
122
+ def get_function_names(self) -> Set[str]:
123
+ """Get all registered function names.
124
+
125
+ Returns:
126
+ Set of function names
127
+ """
128
+ return {func.name for func in self.get_all_functions()}
129
+
130
+ def get_categories(self) -> List[FunctionCategory]:
131
+ """Get all available function categories.
132
+
133
+ Returns:
134
+ List of function categories
135
+ """
136
+ return list(FunctionCategory)
137
+
138
+ def get_subcategories(self) -> List[SubCategory]:
139
+ """Get all available function subcategories.
140
+
141
+ Returns:
142
+ List of function subcategories
143
+ """
144
+ return list(SubCategory)
145
+
146
+ def get_simulation_categories(self) -> List[SimulationCategory]:
147
+ """Get all available simulation categories.
148
+
149
+ Returns:
150
+ List of simulation categories
151
+ """
152
+ return list(SimulationCategory)
153
+
154
+ # Singleton instance
155
+ registry_api = RegistryAPI()
@@ -0,0 +1,136 @@
1
+ from enum import Enum, auto
2
+ from typing import Set, Dict, List, Optional, Tuple
3
+
4
+ class FunctionCategory(Enum):
5
+ """Categories for VEX functions"""
6
+ MOTOR = auto() # Motor control functions
7
+ DRIVETRAIN = auto() # Drivetrain control functions
8
+ SENSOR = auto() # Sensor reading functions
9
+ DISPLAY = auto() # Display output functions
10
+ TIMING = auto() # Timing control functions
11
+ COMPETITION = auto() # Competition control functions
12
+ CONTROLLER = auto() # Controller input functions
13
+ BRAIN = auto() # Brain functions
14
+ UTILITY = auto() # Utility functions
15
+ EVENT = auto() # Event handling
16
+ OTHER = auto() # Other functions
17
+
18
+ class SubCategory(Enum):
19
+ """Subcategories for more fine-grained classification"""
20
+ # Motor subcategories
21
+ MOTOR_SPIN = auto()
22
+ MOTOR_STOP = auto()
23
+ MOTOR_CONFIGURATION = auto()
24
+ MOTOR_MEASUREMENT = auto()
25
+
26
+ # Drivetrain subcategories
27
+ DRIVE_MOVEMENT = auto()
28
+ DRIVE_TURN = auto()
29
+ DRIVE_CONFIGURATION = auto()
30
+
31
+ # Sensor subcategories
32
+ DISTANCE_SENSOR = auto()
33
+ INERTIAL_SENSOR = auto()
34
+ ROTATION_SENSOR = auto()
35
+ OPTICAL_SENSOR = auto()
36
+ VISION_SENSOR = auto()
37
+ LIMIT_SWITCH = auto()
38
+ BUMPER = auto()
39
+ GPS_SENSOR = auto()
40
+
41
+ # Display subcategories
42
+ SCREEN_DRAWING = auto()
43
+ SCREEN_TEXT = auto()
44
+ SCREEN_CLEARING = auto()
45
+
46
+ # Timing subcategories
47
+ WAIT = auto()
48
+ TIMER = auto()
49
+
50
+ # Competition subcategories
51
+ COMPETITION_STATUS = auto()
52
+ COMPETITION_CONTROL = auto()
53
+
54
+ # Controller subcategories
55
+ BUTTON_INPUT = auto()
56
+ JOYSTICK_INPUT = auto()
57
+ CONTROLLER_SCREEN = auto()
58
+ CONTROLLER_RUMBLE = auto()
59
+
60
+ # Brain subcategories
61
+ BRAIN_BATTERY = auto()
62
+ BRAIN_SCREEN = auto()
63
+ BRAIN_BUTTONS = auto()
64
+ BRAIN_SD_CARD = auto()
65
+
66
+ # Utility subcategories
67
+ MATH = auto()
68
+ RANDOM = auto()
69
+ COLOR = auto()
70
+
71
+ # Event subcategories
72
+ CALLBACK = auto()
73
+ EVENT_REGISTRATION = auto()
74
+
75
+ # Other subcategories
76
+ SYSTEM = auto()
77
+ DEBUGGING = auto()
78
+
79
+ class FunctionCategorizer:
80
+ """Utility for categorizing VEX functions"""
81
+
82
+ def __init__(self):
83
+ self.category_patterns: Dict[FunctionCategory, List[str]] = {
84
+ FunctionCategory.MOTOR: ["motor", "spin", "velocity", "torque", "efficiency"],
85
+ FunctionCategory.DRIVETRAIN: ["drive", "turn", "drivetrain"],
86
+ FunctionCategory.SENSOR: ["sensor", "distance", "inertial", "rotation", "optical", "vision", "limit", "bumper", "gps"],
87
+ FunctionCategory.DISPLAY: ["display", "print", "draw", "screen", "clear"],
88
+ FunctionCategory.TIMING: ["wait", "sleep", "delay", "timer"],
89
+ FunctionCategory.COMPETITION: ["competition", "autonomous", "driver"],
90
+ FunctionCategory.CONTROLLER: ["controller", "button", "joystick", "rumble"],
91
+ FunctionCategory.BRAIN: ["brain", "battery"],
92
+ FunctionCategory.UTILITY: ["random", "math", "color"],
93
+ FunctionCategory.EVENT: ["event", "callback", "when", "register"],
94
+ }
95
+
96
+ self.subcategory_patterns: Dict[SubCategory, List[str]] = {
97
+ # Motor subcategories
98
+ SubCategory.MOTOR_SPIN: ["spin", "rotate"],
99
+ SubCategory.MOTOR_STOP: ["stop", "brake"],
100
+ SubCategory.MOTOR_CONFIGURATION: ["set_", "configure"],
101
+ SubCategory.MOTOR_MEASUREMENT: ["current", "temperature", "velocity", "position"],
102
+
103
+ # Additional subcategory patterns can be added as needed
104
+ }
105
+
106
+ def categorize_function(self,
107
+ function_name: str,
108
+ description: str = "") -> Tuple[FunctionCategory, Optional[SubCategory]]:
109
+ """Categorize a function based on its name and description"""
110
+ function_name = function_name.lower()
111
+ description = description.lower()
112
+
113
+ # Try to find the main category
114
+ category = FunctionCategory.OTHER
115
+ for cat, patterns in self.category_patterns.items():
116
+ for pattern in patterns:
117
+ if pattern in function_name or pattern in description:
118
+ category = cat
119
+ break
120
+ if category != FunctionCategory.OTHER:
121
+ break
122
+
123
+ # Try to find the subcategory
124
+ subcategory = None
125
+ for subcat, patterns in self.subcategory_patterns.items():
126
+ for pattern in patterns:
127
+ if pattern in function_name or pattern in description:
128
+ subcategory = subcat
129
+ break
130
+ if subcategory:
131
+ break
132
+
133
+ return category, subcategory
134
+
135
+ # Singleton instance
136
+ categorizer = FunctionCategorizer()
@@ -0,0 +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():
78
+ language_mapper.register_mapping(py_name, cpp_name)
@@ -0,0 +1,153 @@
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()