vex-ast 0.1.0__py3-none-any.whl → 0.2.1__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/README.md +51 -0
- vex_ast/READMEAPI.md +318 -0
- vex_ast/__init__.py +20 -17
- vex_ast/ast/README.md +87 -0
- vex_ast/ast/__init__.py +1 -1
- vex_ast/ast/navigator.py +12 -0
- vex_ast/parser/README.md +47 -0
- vex_ast/parser/__init__.py +27 -0
- vex_ast/registry/README.md +29 -0
- vex_ast/registry/functions/__init__.py +11 -0
- vex_ast/registry/functions/display.py +147 -0
- vex_ast/registry/functions/drivetrain.py +163 -0
- vex_ast/registry/functions/initialize.py +28 -0
- vex_ast/registry/functions/motor.py +140 -0
- vex_ast/registry/functions/sensors.py +195 -0
- vex_ast/registry/functions/timing.py +104 -0
- vex_ast/types/README.md +26 -0
- vex_ast/types/__init__.py +140 -0
- vex_ast/types/base.py +84 -0
- vex_ast/types/enums.py +97 -0
- vex_ast/types/objects.py +64 -0
- vex_ast/types/primitives.py +69 -0
- vex_ast/types/type_checker.py +32 -0
- vex_ast/utils/README.md +39 -0
- vex_ast/utils/__init__.py +38 -0
- vex_ast/utils/type_definitions.py +9 -0
- vex_ast/visitors/README.md +49 -0
- vex_ast/visitors/__init__.py +28 -0
- {vex_ast-0.1.0.dist-info → vex_ast-0.2.1.dist-info}/METADATA +9 -11
- vex_ast-0.2.1.dist-info/RECORD +63 -0
- vex_ast-0.2.1.dist-info/licenses/LICENSE +1 -0
- vex_ast-0.1.0.dist-info/RECORD +0 -41
- {vex_ast-0.1.0.dist-info → vex_ast-0.2.1.dist-info}/WHEEL +0 -0
- {vex_ast-0.1.0.dist-info → vex_ast-0.2.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,104 @@
|
|
1
|
+
from ..registry import registry
|
2
|
+
from ..signature import VexFunctionSignature, VexFunctionParameter, ParameterMode, SimulationCategory
|
3
|
+
from ...types.base import VOID, ANY
|
4
|
+
from ...types.primitives import INT, FLOAT, BOOL
|
5
|
+
from ...types.enums import TIME_UNITS
|
6
|
+
from ...types.objects import TIMER
|
7
|
+
|
8
|
+
def register_timing_functions():
|
9
|
+
"""Register timing-related functions in the registry"""
|
10
|
+
|
11
|
+
# Global wait function
|
12
|
+
wait_params = [
|
13
|
+
VexFunctionParameter("time", FLOAT, description="Time to wait"),
|
14
|
+
VexFunctionParameter("units", TIME_UNITS, "MSEC", description="Time units")
|
15
|
+
]
|
16
|
+
|
17
|
+
wait_signature = VexFunctionSignature(
|
18
|
+
name="wait",
|
19
|
+
return_type=VOID,
|
20
|
+
parameters=wait_params,
|
21
|
+
description="Wait for a specified amount of time",
|
22
|
+
category=SimulationCategory.TIMING_CONTROL,
|
23
|
+
python_name="wait",
|
24
|
+
cpp_name="wait"
|
25
|
+
)
|
26
|
+
|
27
|
+
registry.register_function(wait_signature)
|
28
|
+
|
29
|
+
# Timer functions
|
30
|
+
|
31
|
+
# Timer.time() method
|
32
|
+
time_params = [
|
33
|
+
VexFunctionParameter("units", TIME_UNITS, "MSEC", description="Time units")
|
34
|
+
]
|
35
|
+
|
36
|
+
time_signature = VexFunctionSignature(
|
37
|
+
name="time",
|
38
|
+
return_type=FLOAT,
|
39
|
+
parameters=time_params,
|
40
|
+
description="Get the current time of the timer",
|
41
|
+
category=SimulationCategory.TIMING_CONTROL,
|
42
|
+
python_name="time",
|
43
|
+
cpp_name="time",
|
44
|
+
object_type=TIMER,
|
45
|
+
method_name="time"
|
46
|
+
)
|
47
|
+
|
48
|
+
registry.register_function(time_signature)
|
49
|
+
|
50
|
+
# Timer.clear() method
|
51
|
+
clear_signature = VexFunctionSignature(
|
52
|
+
name="clear",
|
53
|
+
return_type=VOID,
|
54
|
+
parameters=[],
|
55
|
+
description="Clear the timer",
|
56
|
+
category=SimulationCategory.TIMING_CONTROL,
|
57
|
+
python_name="clear",
|
58
|
+
cpp_name="clear",
|
59
|
+
object_type=TIMER,
|
60
|
+
method_name="clear"
|
61
|
+
)
|
62
|
+
|
63
|
+
registry.register_function(clear_signature)
|
64
|
+
|
65
|
+
# Timer.reset() method
|
66
|
+
reset_signature = VexFunctionSignature(
|
67
|
+
name="reset",
|
68
|
+
return_type=VOID,
|
69
|
+
parameters=[],
|
70
|
+
description="Reset the timer",
|
71
|
+
category=SimulationCategory.TIMING_CONTROL,
|
72
|
+
python_name="reset",
|
73
|
+
cpp_name="reset",
|
74
|
+
object_type=TIMER,
|
75
|
+
method_name="reset"
|
76
|
+
)
|
77
|
+
|
78
|
+
registry.register_function(reset_signature)
|
79
|
+
|
80
|
+
# Timer.event() method
|
81
|
+
event_params = [
|
82
|
+
VexFunctionParameter("callback", ANY, description="Callback function to execute"),
|
83
|
+
VexFunctionParameter("delay", FLOAT, description="Time delay before callback execution"),
|
84
|
+
VexFunctionParameter("units", TIME_UNITS, "MSEC", description="Time units")
|
85
|
+
]
|
86
|
+
|
87
|
+
event_signature = VexFunctionSignature(
|
88
|
+
name="event",
|
89
|
+
return_type=VOID,
|
90
|
+
parameters=event_params,
|
91
|
+
description="Register a callback function to be called after a delay",
|
92
|
+
category=SimulationCategory.EVENT_HANDLING,
|
93
|
+
python_name="event",
|
94
|
+
cpp_name="event",
|
95
|
+
object_type=TIMER,
|
96
|
+
method_name="event"
|
97
|
+
)
|
98
|
+
|
99
|
+
registry.register_function(event_signature)
|
100
|
+
|
101
|
+
# Add more timing functions as needed...
|
102
|
+
|
103
|
+
if __name__ == "__main__":
|
104
|
+
register_timing_functions()
|
vex_ast/types/README.md
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# VEX AST Types Package (vex_ast.types)
|
2
|
+
|
3
|
+
This package defines the type system used for the VEX V5 Robot Python language.
|
4
|
+
|
5
|
+
Purpose
|
6
|
+
|
7
|
+
The type system provides a way to represent and reason about the types of values in VEX code. This information is used for type checking, code optimization, and other purposes.
|
8
|
+
|
9
|
+
Structure
|
10
|
+
|
11
|
+
The package is organized into several modules:
|
12
|
+
|
13
|
+
* `base.py`: Defines base classes for types.
|
14
|
+
* `enums.py`: Defines enums for different type categories.
|
15
|
+
* `objects.py`: Defines classes for representing objects.
|
16
|
+
* `primitives.py`: Defines classes for representing primitive types (e.g., int, float, string, boolean).
|
17
|
+
* `type_checker.py`: Implements the type checking logic.
|
18
|
+
|
19
|
+
Key Concepts
|
20
|
+
|
21
|
+
* Types: Represent the kind of value that a variable or expression can have.
|
22
|
+
* Type checking: The process of verifying that the types in a program are consistent.
|
23
|
+
|
24
|
+
Usage
|
25
|
+
|
26
|
+
The type system is used internally by the VEX AST parser, type checker, and other tools. It is not typically accessed directly by users.
|
@@ -0,0 +1,140 @@
|
|
1
|
+
"""
|
2
|
+
Types package for VEX AST.
|
3
|
+
|
4
|
+
This package provides type definitions and type checking functionality for VEX AST.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from .base import (
|
8
|
+
VexType,
|
9
|
+
VoidType,
|
10
|
+
AnyType,
|
11
|
+
TypeRegistry,
|
12
|
+
VOID,
|
13
|
+
ANY,
|
14
|
+
type_registry
|
15
|
+
)
|
16
|
+
|
17
|
+
from .primitives import (
|
18
|
+
PrimitiveType,
|
19
|
+
IntegerType,
|
20
|
+
FloatType,
|
21
|
+
BooleanType,
|
22
|
+
StringType,
|
23
|
+
INT,
|
24
|
+
FLOAT,
|
25
|
+
BOOL,
|
26
|
+
STRING
|
27
|
+
)
|
28
|
+
|
29
|
+
from .objects import (
|
30
|
+
ObjectType,
|
31
|
+
MOTOR,
|
32
|
+
MOTOR_GROUP,
|
33
|
+
DRIVETRAIN,
|
34
|
+
BRAIN,
|
35
|
+
CONTROLLER,
|
36
|
+
INERTIAL,
|
37
|
+
DISTANCE,
|
38
|
+
ROTATION,
|
39
|
+
OPTICAL,
|
40
|
+
GPS,
|
41
|
+
ELECTROMAGNETIC,
|
42
|
+
BRAIN_BATTERY,
|
43
|
+
BRAIN_SCREEN,
|
44
|
+
BRAIN_LCD,
|
45
|
+
COMPETITION,
|
46
|
+
TIMER,
|
47
|
+
BUMPER,
|
48
|
+
LIMIT_SWITCH,
|
49
|
+
ENCODER,
|
50
|
+
SONAR,
|
51
|
+
GYRO,
|
52
|
+
PNEUMATIC,
|
53
|
+
VISION
|
54
|
+
)
|
55
|
+
|
56
|
+
from .enums import (
|
57
|
+
EnumType,
|
58
|
+
DIRECTION_TYPE,
|
59
|
+
TURN_TYPE,
|
60
|
+
BRAKE_TYPE,
|
61
|
+
VELOCITY_UNITS,
|
62
|
+
ROTATION_UNITS,
|
63
|
+
TIME_UNITS,
|
64
|
+
DISTANCE_UNITS,
|
65
|
+
CURRENT_UNITS,
|
66
|
+
TORQUE_UNITS,
|
67
|
+
TEMPERATURE_UNITS,
|
68
|
+
ANALOG_UNITS
|
69
|
+
)
|
70
|
+
|
71
|
+
from .type_checker import (
|
72
|
+
TypeChecker,
|
73
|
+
type_checker as check_type_compatibility
|
74
|
+
)
|
75
|
+
|
76
|
+
__all__ = [
|
77
|
+
# Base types
|
78
|
+
"VexType",
|
79
|
+
"VoidType",
|
80
|
+
"AnyType",
|
81
|
+
"TypeRegistry",
|
82
|
+
"VOID",
|
83
|
+
"ANY",
|
84
|
+
"type_registry",
|
85
|
+
|
86
|
+
# Primitive types
|
87
|
+
"PrimitiveType",
|
88
|
+
"IntegerType",
|
89
|
+
"FloatType",
|
90
|
+
"BooleanType",
|
91
|
+
"StringType",
|
92
|
+
"INT",
|
93
|
+
"FLOAT",
|
94
|
+
"BOOL",
|
95
|
+
"STRING",
|
96
|
+
|
97
|
+
# Object types
|
98
|
+
"ObjectType",
|
99
|
+
"MOTOR",
|
100
|
+
"MOTOR_GROUP",
|
101
|
+
"DRIVETRAIN",
|
102
|
+
"BRAIN",
|
103
|
+
"CONTROLLER",
|
104
|
+
"INERTIAL",
|
105
|
+
"DISTANCE",
|
106
|
+
"ROTATION",
|
107
|
+
"OPTICAL",
|
108
|
+
"GPS",
|
109
|
+
"ELECTROMAGNETIC",
|
110
|
+
"BRAIN_BATTERY",
|
111
|
+
"BRAIN_SCREEN",
|
112
|
+
"BRAIN_LCD",
|
113
|
+
"COMPETITION",
|
114
|
+
"TIMER",
|
115
|
+
"BUMPER",
|
116
|
+
"LIMIT_SWITCH",
|
117
|
+
"ENCODER",
|
118
|
+
"SONAR",
|
119
|
+
"GYRO",
|
120
|
+
"PNEUMATIC",
|
121
|
+
"VISION",
|
122
|
+
|
123
|
+
# Enum types
|
124
|
+
"EnumType",
|
125
|
+
"DIRECTION_TYPE",
|
126
|
+
"TURN_TYPE",
|
127
|
+
"BRAKE_TYPE",
|
128
|
+
"VELOCITY_UNITS",
|
129
|
+
"ROTATION_UNITS",
|
130
|
+
"TIME_UNITS",
|
131
|
+
"DISTANCE_UNITS",
|
132
|
+
"CURRENT_UNITS",
|
133
|
+
"TORQUE_UNITS",
|
134
|
+
"TEMPERATURE_UNITS",
|
135
|
+
"ANALOG_UNITS",
|
136
|
+
|
137
|
+
# Type checking
|
138
|
+
"TypeChecker",
|
139
|
+
"check_type_compatibility"
|
140
|
+
]
|
vex_ast/types/base.py
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
from abc import ABC, abstractmethod
|
2
|
+
from typing import Any, Optional, Union, List, Type, Set, TypeVar, Generic
|
3
|
+
|
4
|
+
class VexType(ABC):
|
5
|
+
"""Base abstract class for all VEX types"""
|
6
|
+
|
7
|
+
@property
|
8
|
+
@abstractmethod
|
9
|
+
def name(self) -> str:
|
10
|
+
"""Return the canonical name of this type"""
|
11
|
+
pass
|
12
|
+
|
13
|
+
@abstractmethod
|
14
|
+
def is_compatible_with(self, other: 'VexType') -> bool:
|
15
|
+
"""Check if this type is compatible with another type"""
|
16
|
+
pass
|
17
|
+
|
18
|
+
@abstractmethod
|
19
|
+
def __str__(self) -> str:
|
20
|
+
"""String representation of the type"""
|
21
|
+
pass
|
22
|
+
|
23
|
+
def __eq__(self, other) -> bool:
|
24
|
+
if not isinstance(other, VexType):
|
25
|
+
return False
|
26
|
+
return self.name == other.name
|
27
|
+
|
28
|
+
class VoidType(VexType):
|
29
|
+
"""Represents the void type (no return value)"""
|
30
|
+
|
31
|
+
@property
|
32
|
+
def name(self) -> str:
|
33
|
+
return "void"
|
34
|
+
|
35
|
+
def is_compatible_with(self, other: VexType) -> bool:
|
36
|
+
return isinstance(other, VoidType)
|
37
|
+
|
38
|
+
def __str__(self) -> str:
|
39
|
+
return "void"
|
40
|
+
|
41
|
+
class AnyType(VexType):
|
42
|
+
"""Represents any type (for generic functions)"""
|
43
|
+
|
44
|
+
@property
|
45
|
+
def name(self) -> str:
|
46
|
+
return "any"
|
47
|
+
|
48
|
+
def is_compatible_with(self, other: VexType) -> bool:
|
49
|
+
return True # Any type is compatible with all types
|
50
|
+
|
51
|
+
def __str__(self) -> str:
|
52
|
+
return "any"
|
53
|
+
|
54
|
+
class TypeRegistry:
|
55
|
+
"""Global registry of types to ensure type uniqueness"""
|
56
|
+
|
57
|
+
_instance = None
|
58
|
+
|
59
|
+
def __new__(cls):
|
60
|
+
if cls._instance is None:
|
61
|
+
cls._instance = super(TypeRegistry, cls).__new__(cls)
|
62
|
+
cls._instance._types = {}
|
63
|
+
return cls._instance
|
64
|
+
|
65
|
+
def register_type(self, type_: VexType) -> None:
|
66
|
+
"""Register a type in the registry"""
|
67
|
+
self._types[type_.name] = type_
|
68
|
+
|
69
|
+
def get_type(self, name: str) -> Optional[VexType]:
|
70
|
+
"""Get a type by name"""
|
71
|
+
return self._types.get(name)
|
72
|
+
|
73
|
+
def get_all_types(self) -> List[VexType]:
|
74
|
+
"""Get all registered types"""
|
75
|
+
return list(self._types.values())
|
76
|
+
|
77
|
+
# Singleton instances
|
78
|
+
VOID = VoidType()
|
79
|
+
ANY = AnyType()
|
80
|
+
|
81
|
+
# Global registry
|
82
|
+
type_registry = TypeRegistry()
|
83
|
+
type_registry.register_type(VOID)
|
84
|
+
type_registry.register_type(ANY)
|
vex_ast/types/enums.py
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
from typing import Dict, List, Any, Optional, Set
|
2
|
+
from .base import VexType, type_registry
|
3
|
+
from .primitives import StringType, IntegerType, INT
|
4
|
+
|
5
|
+
class EnumType(VexType):
|
6
|
+
"""Represents a VEX enum type"""
|
7
|
+
|
8
|
+
def __init__(self, name: str, values: Dict[str, Any] = None):
|
9
|
+
self._name = name
|
10
|
+
self._values = values or {}
|
11
|
+
type_registry.register_type(self)
|
12
|
+
|
13
|
+
@property
|
14
|
+
def name(self) -> str:
|
15
|
+
return self._name
|
16
|
+
|
17
|
+
@property
|
18
|
+
def values(self) -> Dict[str, Any]:
|
19
|
+
return self._values.copy()
|
20
|
+
|
21
|
+
def is_compatible_with(self, other: VexType) -> bool:
|
22
|
+
"""Enums are compatible with themselves or with integers"""
|
23
|
+
return isinstance(other, EnumType) and self.name == other.name or isinstance(other, IntegerType)
|
24
|
+
|
25
|
+
def __str__(self) -> str:
|
26
|
+
return f"enum {self._name}"
|
27
|
+
|
28
|
+
def add_value(self, name: str, value: Any) -> None:
|
29
|
+
"""Add a value to the enum"""
|
30
|
+
self._values[name] = value
|
31
|
+
|
32
|
+
def is_valid_value(self, value: Any) -> bool:
|
33
|
+
"""Check if a value is valid for this enum"""
|
34
|
+
return value in self._values.values() or value in self._values
|
35
|
+
|
36
|
+
# Create VEX enum types
|
37
|
+
DIRECTION_TYPE = EnumType("DirectionType", {
|
38
|
+
"FORWARD": 0,
|
39
|
+
"REVERSE": 1
|
40
|
+
})
|
41
|
+
|
42
|
+
TURN_TYPE = EnumType("TurnType", {
|
43
|
+
"LEFT": 0,
|
44
|
+
"RIGHT": 1
|
45
|
+
})
|
46
|
+
|
47
|
+
BRAKE_TYPE = EnumType("BrakeType", {
|
48
|
+
"COAST": 0,
|
49
|
+
"BRAKE": 1,
|
50
|
+
"HOLD": 2
|
51
|
+
})
|
52
|
+
|
53
|
+
VELOCITY_UNITS = EnumType("VelocityUnits", {
|
54
|
+
"PCT": 0, # Percentage
|
55
|
+
"RPM": 1, # Revolutions per minute
|
56
|
+
"DPS": 2 # Degrees per second
|
57
|
+
})
|
58
|
+
|
59
|
+
ROTATION_UNITS = EnumType("RotationUnits", {
|
60
|
+
"DEG": 0, # Degrees
|
61
|
+
"REV": 1, # Revolutions
|
62
|
+
"RAW": 2 # Raw data
|
63
|
+
})
|
64
|
+
|
65
|
+
TIME_UNITS = EnumType("TimeUnits", {
|
66
|
+
"SEC": 0, # Seconds
|
67
|
+
"MSEC": 1 # Milliseconds
|
68
|
+
})
|
69
|
+
|
70
|
+
DISTANCE_UNITS = EnumType("DistanceUnits", {
|
71
|
+
"MM": 0, # Millimeters
|
72
|
+
"IN": 1 # Inches
|
73
|
+
})
|
74
|
+
|
75
|
+
CURRENT_UNITS = EnumType("CurrentUnits", {
|
76
|
+
"AMP": 0 # Amperes
|
77
|
+
})
|
78
|
+
|
79
|
+
TORQUE_UNITS = EnumType("TorqueUnits", {
|
80
|
+
"NM": 0, # Newton meters
|
81
|
+
"INLB": 1 # Inch pounds
|
82
|
+
})
|
83
|
+
|
84
|
+
TEMPERATURE_UNITS = EnumType("TemperatureUnits", {
|
85
|
+
"CELSIUS": 0,
|
86
|
+
"FAHRENHEIT": 1
|
87
|
+
})
|
88
|
+
|
89
|
+
ANALOG_UNITS = EnumType("AnalogUnits", {
|
90
|
+
"PCT": 0, # Percentage
|
91
|
+
"EIGHTBIT": 1, # 8-bit (0-255)
|
92
|
+
"TENBIT": 2, # 10-bit (0-1023)
|
93
|
+
"TWELVEBIT": 3, # 12-bit (0-4095)
|
94
|
+
"MV": 4 # Millivolts
|
95
|
+
})
|
96
|
+
|
97
|
+
# Add more VEX enum types as needed
|
vex_ast/types/objects.py
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
from typing import Optional, List, Dict, Any, Set, TYPE_CHECKING
|
2
|
+
from .base import VexType, type_registry
|
3
|
+
|
4
|
+
# Use TYPE_CHECKING to avoid circular imports
|
5
|
+
if TYPE_CHECKING:
|
6
|
+
from ..registry.signature import VexFunctionSignature
|
7
|
+
|
8
|
+
class ObjectType(VexType):
|
9
|
+
"""Base class for all VEX object types (motors, sensors, etc.)"""
|
10
|
+
|
11
|
+
def __init__(self, name: str, methods: Dict[str, 'VexFunctionSignature'] = None):
|
12
|
+
self._name = name
|
13
|
+
self._methods = methods or {}
|
14
|
+
type_registry.register_type(self)
|
15
|
+
|
16
|
+
@property
|
17
|
+
def name(self) -> str:
|
18
|
+
return self._name
|
19
|
+
|
20
|
+
@property
|
21
|
+
def methods(self) -> Dict[str, Any]: # Use Any instead of forward reference
|
22
|
+
return self._methods
|
23
|
+
|
24
|
+
def add_method(self, method_name: str, signature: Any) -> None: # Use Any instead of forward reference
|
25
|
+
"""Add a method to this object type"""
|
26
|
+
self._methods[method_name] = signature
|
27
|
+
|
28
|
+
def get_method(self, method_name: str) -> Optional[Any]: # Use Any instead of forward reference
|
29
|
+
"""Get a method by name"""
|
30
|
+
return self._methods.get(method_name)
|
31
|
+
|
32
|
+
def is_compatible_with(self, other: VexType) -> bool:
|
33
|
+
"""Objects are compatible only with the same type"""
|
34
|
+
return isinstance(other, ObjectType) and self.name == other.name
|
35
|
+
|
36
|
+
def __str__(self) -> str:
|
37
|
+
return self._name
|
38
|
+
|
39
|
+
# VEX object types - define basic types here, methods will be added later
|
40
|
+
MOTOR = ObjectType("Motor")
|
41
|
+
MOTOR_GROUP = ObjectType("MotorGroup")
|
42
|
+
DRIVETRAIN = ObjectType("Drivetrain")
|
43
|
+
BRAIN = ObjectType("Brain")
|
44
|
+
CONTROLLER = ObjectType("Controller")
|
45
|
+
INERTIAL = ObjectType("Inertial")
|
46
|
+
DISTANCE = ObjectType("Distance")
|
47
|
+
ROTATION = ObjectType("Rotation")
|
48
|
+
OPTICAL = ObjectType("Optical")
|
49
|
+
GPS = ObjectType("GPS")
|
50
|
+
ELECTROMAGNETIC = ObjectType("Electromagnetic")
|
51
|
+
BRAIN_BATTERY = ObjectType("BrainBattery")
|
52
|
+
BRAIN_SCREEN = ObjectType("BrainScreen")
|
53
|
+
BRAIN_LCD = ObjectType("BrainLcd")
|
54
|
+
COMPETITION = ObjectType("Competition")
|
55
|
+
TIMER = ObjectType("Timer")
|
56
|
+
BUMPER = ObjectType("Bumper")
|
57
|
+
LIMIT_SWITCH = ObjectType("LimitSwitch")
|
58
|
+
ENCODER = ObjectType("Encoder")
|
59
|
+
SONAR = ObjectType("Sonar")
|
60
|
+
GYRO = ObjectType("Gyro")
|
61
|
+
PNEUMATIC = ObjectType("Pneumatic")
|
62
|
+
VISION = ObjectType("Vision")
|
63
|
+
|
64
|
+
# Add additional object types as needed
|
@@ -0,0 +1,69 @@
|
|
1
|
+
from typing import Optional, Union, List, Set, Dict, Any
|
2
|
+
from .base import VexType, type_registry
|
3
|
+
|
4
|
+
class PrimitiveType(VexType):
|
5
|
+
"""Base class for primitive types like int, float, string, etc."""
|
6
|
+
|
7
|
+
def __init__(self, name: str):
|
8
|
+
self._name = name
|
9
|
+
type_registry.register_type(self)
|
10
|
+
|
11
|
+
@property
|
12
|
+
def name(self) -> str:
|
13
|
+
return self._name
|
14
|
+
|
15
|
+
def __str__(self) -> str:
|
16
|
+
return self._name
|
17
|
+
|
18
|
+
class NumericType(PrimitiveType):
|
19
|
+
"""Base class for numeric types"""
|
20
|
+
|
21
|
+
def is_compatible_with(self, other: VexType) -> bool:
|
22
|
+
"""Numeric types are compatible with other numeric types"""
|
23
|
+
return isinstance(other, NumericType)
|
24
|
+
|
25
|
+
class IntegerType(NumericType):
|
26
|
+
"""Integer type"""
|
27
|
+
|
28
|
+
def __init__(self):
|
29
|
+
super().__init__("int")
|
30
|
+
|
31
|
+
def is_compatible_with(self, other: VexType) -> bool:
|
32
|
+
"""Integers are compatible with numeric types"""
|
33
|
+
return isinstance(other, NumericType)
|
34
|
+
|
35
|
+
class FloatType(NumericType):
|
36
|
+
"""Float type"""
|
37
|
+
|
38
|
+
def __init__(self):
|
39
|
+
super().__init__("float")
|
40
|
+
|
41
|
+
def is_compatible_with(self, other: VexType) -> bool:
|
42
|
+
"""Floats are compatible with numeric types"""
|
43
|
+
return isinstance(other, NumericType)
|
44
|
+
|
45
|
+
class BooleanType(PrimitiveType):
|
46
|
+
"""Boolean type"""
|
47
|
+
|
48
|
+
def __init__(self):
|
49
|
+
super().__init__("bool")
|
50
|
+
|
51
|
+
def is_compatible_with(self, other: VexType) -> bool:
|
52
|
+
"""Booleans are only compatible with booleans"""
|
53
|
+
return isinstance(other, BooleanType)
|
54
|
+
|
55
|
+
class StringType(PrimitiveType):
|
56
|
+
"""String type"""
|
57
|
+
|
58
|
+
def __init__(self):
|
59
|
+
super().__init__("string")
|
60
|
+
|
61
|
+
def is_compatible_with(self, other: VexType) -> bool:
|
62
|
+
"""Strings are only compatible with strings"""
|
63
|
+
return isinstance(other, StringType)
|
64
|
+
|
65
|
+
# Singleton instances
|
66
|
+
INT = IntegerType()
|
67
|
+
FLOAT = FloatType()
|
68
|
+
BOOL = BooleanType()
|
69
|
+
STRING = StringType()
|
@@ -0,0 +1,32 @@
|
|
1
|
+
from typing import Optional, Any, List, Dict, Union, Tuple
|
2
|
+
from .base import VexType, ANY
|
3
|
+
from .primitives import INT, FLOAT, BOOL, STRING
|
4
|
+
|
5
|
+
class TypeChecker:
|
6
|
+
"""Utility for checking type compatibility"""
|
7
|
+
|
8
|
+
def is_compatible(self, value_type: VexType, expected_type: VexType) -> bool:
|
9
|
+
"""Check if value_type is compatible with expected_type"""
|
10
|
+
# Any type is compatible with anything
|
11
|
+
if expected_type == ANY:
|
12
|
+
return True
|
13
|
+
|
14
|
+
return value_type.is_compatible_with(expected_type)
|
15
|
+
|
16
|
+
def get_python_type(self, value: Any) -> Optional[VexType]:
|
17
|
+
"""Convert a Python value to a VEX type"""
|
18
|
+
if value is None:
|
19
|
+
return None
|
20
|
+
if isinstance(value, bool):
|
21
|
+
return BOOL
|
22
|
+
if isinstance(value, int):
|
23
|
+
return INT
|
24
|
+
if isinstance(value, float):
|
25
|
+
return FLOAT
|
26
|
+
if isinstance(value, str):
|
27
|
+
return STRING
|
28
|
+
# Complex objects would need additional mapping logic
|
29
|
+
return None
|
30
|
+
|
31
|
+
# Singleton instance
|
32
|
+
type_checker = TypeChecker()
|
vex_ast/utils/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
Utilities (vex_ast.utils)
|
2
|
+
|
3
|
+
This directory contains utility modules that provide supporting functionality for the VEX AST parser and other components.
|
4
|
+
|
5
|
+
Purpose
|
6
|
+
|
7
|
+
These modules encapsulate common tasks and data structures needed across the vex_ast package, promoting code reuse and separation of concerns.
|
8
|
+
|
9
|
+
Modules
|
10
|
+
|
11
|
+
Error Handling (errors.py):
|
12
|
+
|
13
|
+
ErrorType: An enum defining categories of errors (e.g., PARSER_ERROR, SEMANTIC_ERROR).
|
14
|
+
|
15
|
+
Error: A class representing a single error instance, containing the type, message, optional source location, and optional suggestion.
|
16
|
+
|
17
|
+
ErrorHandler: A central class for collecting and managing errors encountered during parsing or AST processing. It allows registering observers and can optionally raise exceptions immediately upon error detection.
|
18
|
+
|
19
|
+
VexAstError, VexSyntaxError: Custom exception classes for AST-related errors, with VexSyntaxError specifically for parsing issues.
|
20
|
+
|
21
|
+
Importance: Provides a robust way to handle and report problems found in the source code or during AST processing, crucial for user feedback and debugging.
|
22
|
+
|
23
|
+
Source Location (source_location.py):
|
24
|
+
|
25
|
+
SourceLocation: A dataclass representing a position or span within the original source code file. It includes line and column numbers (and optionally end line/column and filename).
|
26
|
+
|
27
|
+
Importance: Allows AST nodes and errors to be linked back to their origin in the source code, which is essential for accurate error reporting, debugging tools, and source mapping.
|
28
|
+
|
29
|
+
Usage
|
30
|
+
|
31
|
+
These utilities are primarily used internally by other parts of the vex_ast package:
|
32
|
+
|
33
|
+
The PythonParser uses the ErrorHandler to report syntax errors or issues during AST conversion. It uses SourceLocation to tag generated AST nodes with their origin.
|
34
|
+
|
35
|
+
AST Node classes store SourceLocation objects.
|
36
|
+
|
37
|
+
Visitors might use the ErrorHandler if they perform analysis that detects semantic errors.
|
38
|
+
|
39
|
+
Error messages often include the string representation of a SourceLocation.
|
vex_ast/utils/__init__.py
CHANGED
@@ -0,0 +1,38 @@
|
|
1
|
+
"""
|
2
|
+
Utilities package for VEX AST.
|
3
|
+
|
4
|
+
This package provides utility functions and classes for working with the AST.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from .errors import (
|
8
|
+
ErrorHandler,
|
9
|
+
ErrorType,
|
10
|
+
VexSyntaxError,
|
11
|
+
VexAstError,
|
12
|
+
Error
|
13
|
+
)
|
14
|
+
from .source_location import (
|
15
|
+
SourceLocation,
|
16
|
+
)
|
17
|
+
from .type_definitions import (
|
18
|
+
NodeType,
|
19
|
+
VisitorType,
|
20
|
+
TransformerType
|
21
|
+
)
|
22
|
+
|
23
|
+
__all__ = [
|
24
|
+
# Error handling
|
25
|
+
"ErrorHandler",
|
26
|
+
"ErrorType",
|
27
|
+
"VexSyntaxError",
|
28
|
+
"VexAstError",
|
29
|
+
"Error",
|
30
|
+
|
31
|
+
# Source location
|
32
|
+
"SourceLocation",
|
33
|
+
|
34
|
+
# Type definitions
|
35
|
+
"NodeType",
|
36
|
+
"VisitorType",
|
37
|
+
"TransformerType"
|
38
|
+
]
|