vex-ast 0.2.5__py3-none-any.whl → 0.2.7__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 +101 -51
- vex_ast/READMEAPI.md +133 -318
- vex_ast/__init__.py +81 -81
- vex_ast/ast/README.md +87 -87
- vex_ast/ast/__init__.py +74 -74
- vex_ast/ast/core.py +71 -71
- vex_ast/ast/expressions.py +276 -276
- vex_ast/ast/interfaces.py +208 -208
- vex_ast/ast/literals.py +80 -80
- vex_ast/ast/navigator.py +241 -225
- vex_ast/ast/operators.py +135 -135
- vex_ast/ast/statements.py +351 -351
- vex_ast/ast/validators.py +121 -121
- vex_ast/ast/vex_nodes.py +279 -279
- vex_ast/parser/README.md +47 -47
- vex_ast/parser/__init__.py +26 -26
- vex_ast/parser/factory.py +190 -190
- vex_ast/parser/interfaces.py +34 -34
- vex_ast/parser/python_parser.py +831 -831
- vex_ast/registry/README.md +107 -29
- vex_ast/registry/__init__.py +51 -51
- vex_ast/registry/api.py +190 -155
- vex_ast/registry/categories.py +179 -136
- vex_ast/registry/functions/__init__.py +10 -10
- vex_ast/registry/functions/constructors.py +71 -35
- vex_ast/registry/functions/display.py +146 -146
- vex_ast/registry/functions/drivetrain.py +163 -163
- vex_ast/registry/functions/initialize.py +31 -31
- vex_ast/registry/functions/motor.py +140 -140
- vex_ast/registry/functions/sensors.py +194 -194
- vex_ast/registry/functions/timing.py +103 -103
- vex_ast/registry/language_map.py +77 -77
- vex_ast/registry/registry.py +164 -153
- vex_ast/registry/signature.py +269 -191
- vex_ast/registry/simulation_behavior.py +8 -8
- vex_ast/registry/validation.py +43 -43
- vex_ast/serialization/__init__.py +37 -37
- vex_ast/serialization/json_deserializer.py +284 -284
- vex_ast/serialization/json_serializer.py +148 -148
- vex_ast/serialization/schema.py +492 -492
- vex_ast/types/README.md +78 -26
- vex_ast/types/__init__.py +140 -140
- vex_ast/types/base.py +83 -83
- vex_ast/types/enums.py +122 -122
- vex_ast/types/objects.py +64 -64
- vex_ast/types/primitives.py +68 -68
- vex_ast/types/type_checker.py +31 -31
- vex_ast/utils/README.md +39 -39
- vex_ast/utils/__init__.py +37 -37
- vex_ast/utils/errors.py +112 -112
- vex_ast/utils/source_location.py +38 -38
- vex_ast/utils/type_definitions.py +8 -8
- vex_ast/visitors/README.md +49 -49
- vex_ast/visitors/__init__.py +27 -27
- vex_ast/visitors/analyzer.py +102 -102
- vex_ast/visitors/base.py +133 -133
- vex_ast/visitors/printer.py +196 -196
- {vex_ast-0.2.5.dist-info → vex_ast-0.2.7.dist-info}/METADATA +206 -174
- vex_ast-0.2.7.dist-info/RECORD +64 -0
- vex_ast-0.2.5.dist-info/RECORD +0 -64
- {vex_ast-0.2.5.dist-info → vex_ast-0.2.7.dist-info}/WHEEL +0 -0
- {vex_ast-0.2.5.dist-info → vex_ast-0.2.7.dist-info}/licenses/LICENSE +0 -0
- {vex_ast-0.2.5.dist-info → vex_ast-0.2.7.dist-info}/top_level.txt +0 -0
vex_ast/types/enums.py
CHANGED
@@ -1,122 +1,122 @@
|
|
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
|
-
# Port type enum
|
98
|
-
PORT_TYPE = EnumType("PortType", {
|
99
|
-
"PORT1": 1,
|
100
|
-
"PORT2": 2,
|
101
|
-
"PORT3": 3,
|
102
|
-
"PORT4": 4,
|
103
|
-
"PORT5": 5,
|
104
|
-
"PORT6": 6,
|
105
|
-
"PORT7": 7,
|
106
|
-
"PORT8": 8,
|
107
|
-
"PORT9": 9,
|
108
|
-
"PORT10": 10,
|
109
|
-
"PORT11": 11,
|
110
|
-
"PORT12": 12,
|
111
|
-
"PORT13": 13,
|
112
|
-
"PORT14": 14,
|
113
|
-
"PORT15": 15,
|
114
|
-
"PORT16": 16,
|
115
|
-
"PORT17": 17,
|
116
|
-
"PORT18": 18,
|
117
|
-
"PORT19": 19,
|
118
|
-
"PORT20": 20,
|
119
|
-
"PORT21": 21
|
120
|
-
})
|
121
|
-
|
122
|
-
# Add more VEX enum types as needed
|
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
|
+
# Port type enum
|
98
|
+
PORT_TYPE = EnumType("PortType", {
|
99
|
+
"PORT1": 1,
|
100
|
+
"PORT2": 2,
|
101
|
+
"PORT3": 3,
|
102
|
+
"PORT4": 4,
|
103
|
+
"PORT5": 5,
|
104
|
+
"PORT6": 6,
|
105
|
+
"PORT7": 7,
|
106
|
+
"PORT8": 8,
|
107
|
+
"PORT9": 9,
|
108
|
+
"PORT10": 10,
|
109
|
+
"PORT11": 11,
|
110
|
+
"PORT12": 12,
|
111
|
+
"PORT13": 13,
|
112
|
+
"PORT14": 14,
|
113
|
+
"PORT15": 15,
|
114
|
+
"PORT16": 16,
|
115
|
+
"PORT17": 17,
|
116
|
+
"PORT18": 18,
|
117
|
+
"PORT19": 19,
|
118
|
+
"PORT20": 20,
|
119
|
+
"PORT21": 21
|
120
|
+
})
|
121
|
+
|
122
|
+
# Add more VEX enum types as needed
|
vex_ast/types/objects.py
CHANGED
@@ -1,64 +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
|
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
|
vex_ast/types/primitives.py
CHANGED
@@ -1,69 +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()
|
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
69
|
STRING = StringType()
|
vex_ast/types/type_checker.py
CHANGED
@@ -1,32 +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
|
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
32
|
type_checker = TypeChecker()
|
vex_ast/utils/README.md
CHANGED
@@ -1,39 +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.
|
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.
|