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.
- vex_ast/__init__.py +65 -0
- vex_ast/ast/__init__.py +75 -0
- vex_ast/ast/core.py +71 -0
- vex_ast/ast/expressions.py +233 -0
- vex_ast/ast/interfaces.py +192 -0
- vex_ast/ast/literals.py +80 -0
- vex_ast/ast/navigator.py +213 -0
- vex_ast/ast/operators.py +136 -0
- vex_ast/ast/statements.py +351 -0
- vex_ast/ast/validators.py +114 -0
- vex_ast/ast/vex_nodes.py +241 -0
- vex_ast/parser/__init__.py +0 -0
- vex_ast/parser/factory.py +179 -0
- vex_ast/parser/interfaces.py +35 -0
- vex_ast/parser/python_parser.py +725 -0
- vex_ast/parser/strategies.py +0 -0
- vex_ast/registry/__init__.py +51 -0
- vex_ast/registry/api.py +155 -0
- vex_ast/registry/categories.py +136 -0
- vex_ast/registry/language_map.py +78 -0
- vex_ast/registry/registry.py +153 -0
- vex_ast/registry/signature.py +143 -0
- vex_ast/registry/simulation_behavior.py +9 -0
- vex_ast/registry/validation.py +44 -0
- vex_ast/serialization/__init__.py +37 -0
- vex_ast/serialization/json_deserializer.py +264 -0
- vex_ast/serialization/json_serializer.py +148 -0
- vex_ast/serialization/schema.py +471 -0
- vex_ast/utils/__init__.py +0 -0
- vex_ast/utils/errors.py +112 -0
- vex_ast/utils/source_location.py +39 -0
- vex_ast/utils/type_definitions.py +0 -0
- vex_ast/visitors/__init__.py +0 -0
- vex_ast/visitors/analyzer.py +103 -0
- vex_ast/visitors/base.py +130 -0
- vex_ast/visitors/printer.py +145 -0
- vex_ast/visitors/transformer.py +0 -0
- vex_ast-0.1.0.dist-info/METADATA +176 -0
- vex_ast-0.1.0.dist-info/RECORD +41 -0
- vex_ast-0.1.0.dist-info/WHEEL +5 -0
- 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
|
+
]
|
vex_ast/registry/api.py
ADDED
@@ -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()
|