vex-ast 0.2.5__py3-none-any.whl → 0.2.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +225 -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.6.dist-info}/METADATA +206 -174
- vex_ast-0.2.6.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.6.dist-info}/WHEEL +0 -0
- {vex_ast-0.2.5.dist-info → vex_ast-0.2.6.dist-info}/licenses/LICENSE +0 -0
- {vex_ast-0.2.5.dist-info → vex_ast-0.2.6.dist-info}/top_level.txt +0 -0
vex_ast/__init__.py
CHANGED
@@ -1,81 +1,81 @@
|
|
1
|
-
"""
|
2
|
-
VEX AST Generator Package.
|
3
|
-
|
4
|
-
Provides tools for parsing VEX V5 code and generating an Abstract Syntax Tree (AST).
|
5
|
-
"""
|
6
|
-
|
7
|
-
# Core functionality
|
8
|
-
from .ast.core import Program
|
9
|
-
from .parser.python_parser import parse_string, parse_file
|
10
|
-
|
11
|
-
# AST Navigation
|
12
|
-
from .ast.navigator import AstNavigator, create_navigator
|
13
|
-
|
14
|
-
# Visitors
|
15
|
-
from .visitors.printer import PrintVisitor
|
16
|
-
from .visitors.analyzer import NodeCounter, VariableCollector
|
17
|
-
|
18
|
-
# Error handling
|
19
|
-
from .utils.errors import ErrorHandler, ErrorType, VexSyntaxError, VexAstError, Error
|
20
|
-
|
21
|
-
# Registry
|
22
|
-
from .registry.api import registry_api
|
23
|
-
from .registry import initialize
|
24
|
-
|
25
|
-
# Serialization
|
26
|
-
from .serialization.json_serializer import serialize_ast_to_dict, serialize_ast_to_json
|
27
|
-
from .serialization.json_deserializer import deserialize_ast_from_dict, deserialize_ast_from_json
|
28
|
-
from .serialization.schema import generate_ast_schema, export_schema_to_file
|
29
|
-
|
30
|
-
__version__ = "0.2.0"
|
31
|
-
|
32
|
-
# Initialize the registry with default functions
|
33
|
-
try:
|
34
|
-
# Explicitly import and initialize all registry functions
|
35
|
-
from .registry.functions.initialize import initialize_registry
|
36
|
-
initialize_registry()
|
37
|
-
|
38
|
-
# Verify registry has been populated
|
39
|
-
if len(registry_api.get_all_functions()) == 0:
|
40
|
-
print("Warning: Registry initialization did not populate any functions")
|
41
|
-
else:
|
42
|
-
print(f"VEX function registry initialized successfully with {len(registry_api.get_all_functions())} functions")
|
43
|
-
except Exception as e:
|
44
|
-
print(f"Error initializing VEX function registry: {e}")
|
45
|
-
import traceback
|
46
|
-
traceback.print_exc()
|
47
|
-
|
48
|
-
__all__ = [
|
49
|
-
# Core functionality
|
50
|
-
"Program",
|
51
|
-
"parse_string",
|
52
|
-
"parse_file",
|
53
|
-
|
54
|
-
# AST Navigation
|
55
|
-
"AstNavigator",
|
56
|
-
"create_navigator",
|
57
|
-
|
58
|
-
# Visitors
|
59
|
-
"PrintVisitor",
|
60
|
-
"NodeCounter",
|
61
|
-
"VariableCollector",
|
62
|
-
|
63
|
-
# Error handling
|
64
|
-
"ErrorHandler",
|
65
|
-
"ErrorType",
|
66
|
-
"VexSyntaxError",
|
67
|
-
"VexAstError",
|
68
|
-
"Error",
|
69
|
-
|
70
|
-
# Registry
|
71
|
-
"registry_api",
|
72
|
-
"initialize",
|
73
|
-
|
74
|
-
# Serialization
|
75
|
-
"serialize_ast_to_dict",
|
76
|
-
"serialize_ast_to_json",
|
77
|
-
"deserialize_ast_from_dict",
|
78
|
-
"deserialize_ast_from_json",
|
79
|
-
"generate_ast_schema",
|
80
|
-
"export_schema_to_file"
|
81
|
-
]
|
1
|
+
"""
|
2
|
+
VEX AST Generator Package.
|
3
|
+
|
4
|
+
Provides tools for parsing VEX V5 code and generating an Abstract Syntax Tree (AST).
|
5
|
+
"""
|
6
|
+
|
7
|
+
# Core functionality
|
8
|
+
from .ast.core import Program
|
9
|
+
from .parser.python_parser import parse_string, parse_file
|
10
|
+
|
11
|
+
# AST Navigation
|
12
|
+
from .ast.navigator import AstNavigator, create_navigator
|
13
|
+
|
14
|
+
# Visitors
|
15
|
+
from .visitors.printer import PrintVisitor
|
16
|
+
from .visitors.analyzer import NodeCounter, VariableCollector
|
17
|
+
|
18
|
+
# Error handling
|
19
|
+
from .utils.errors import ErrorHandler, ErrorType, VexSyntaxError, VexAstError, Error
|
20
|
+
|
21
|
+
# Registry
|
22
|
+
from .registry.api import registry_api
|
23
|
+
from .registry import initialize
|
24
|
+
|
25
|
+
# Serialization
|
26
|
+
from .serialization.json_serializer import serialize_ast_to_dict, serialize_ast_to_json
|
27
|
+
from .serialization.json_deserializer import deserialize_ast_from_dict, deserialize_ast_from_json
|
28
|
+
from .serialization.schema import generate_ast_schema, export_schema_to_file
|
29
|
+
|
30
|
+
__version__ = "0.2.0"
|
31
|
+
|
32
|
+
# Initialize the registry with default functions
|
33
|
+
try:
|
34
|
+
# Explicitly import and initialize all registry functions
|
35
|
+
from .registry.functions.initialize import initialize_registry
|
36
|
+
initialize_registry()
|
37
|
+
|
38
|
+
# Verify registry has been populated
|
39
|
+
if len(registry_api.get_all_functions()) == 0:
|
40
|
+
print("Warning: Registry initialization did not populate any functions")
|
41
|
+
else:
|
42
|
+
print(f"VEX function registry initialized successfully with {len(registry_api.get_all_functions())} functions")
|
43
|
+
except Exception as e:
|
44
|
+
print(f"Error initializing VEX function registry: {e}")
|
45
|
+
import traceback
|
46
|
+
traceback.print_exc()
|
47
|
+
|
48
|
+
__all__ = [
|
49
|
+
# Core functionality
|
50
|
+
"Program",
|
51
|
+
"parse_string",
|
52
|
+
"parse_file",
|
53
|
+
|
54
|
+
# AST Navigation
|
55
|
+
"AstNavigator",
|
56
|
+
"create_navigator",
|
57
|
+
|
58
|
+
# Visitors
|
59
|
+
"PrintVisitor",
|
60
|
+
"NodeCounter",
|
61
|
+
"VariableCollector",
|
62
|
+
|
63
|
+
# Error handling
|
64
|
+
"ErrorHandler",
|
65
|
+
"ErrorType",
|
66
|
+
"VexSyntaxError",
|
67
|
+
"VexAstError",
|
68
|
+
"Error",
|
69
|
+
|
70
|
+
# Registry
|
71
|
+
"registry_api",
|
72
|
+
"initialize",
|
73
|
+
|
74
|
+
# Serialization
|
75
|
+
"serialize_ast_to_dict",
|
76
|
+
"serialize_ast_to_json",
|
77
|
+
"deserialize_ast_from_dict",
|
78
|
+
"deserialize_ast_from_json",
|
79
|
+
"generate_ast_schema",
|
80
|
+
"export_schema_to_file"
|
81
|
+
]
|
vex_ast/ast/README.md
CHANGED
@@ -1,87 +1,87 @@
|
|
1
|
-
AST Node Definitions (vex_ast.ast)
|
2
|
-
|
3
|
-
This directory defines the structure and types of nodes used in the Abstract Syntax Tree (AST) representation of VEX V5 Python code.
|
4
|
-
|
5
|
-
Purpose
|
6
|
-
|
7
|
-
The AST provides a structured, hierarchical representation of the source code, abstracting away the specific syntax details. This structure is the foundation for analysis, transformation, and interpretation of the code.
|
8
|
-
|
9
|
-
Core Concepts
|
10
|
-
|
11
|
-
Interfaces (interfaces.py): Defines the fundamental protocols (IAstNode, IExpression, IStatement, ILiteral, IVisitor) that all nodes and visitors adhere to. This ensures a consistent structure.
|
12
|
-
|
13
|
-
Base Classes (core.py): Provides abstract base classes (AstNode, Expression, Statement) that implement common functionality like location tracking and the basic accept method for the Visitor pattern. Program is the root node type.
|
14
|
-
|
15
|
-
Visitor Pattern: Each node implements an accept(visitor) method, allowing external IVisitor objects to operate on the AST without modifying the node classes themselves.
|
16
|
-
|
17
|
-
Child Nodes: Each node provides a get_children() method to facilitate traversal of the tree.
|
18
|
-
|
19
|
-
Source Location: Nodes can store optional SourceLocation information (from vex_ast.utils) linking them back to the original code.
|
20
|
-
|
21
|
-
Node Categories
|
22
|
-
|
23
|
-
The AST nodes are organized into logical categories:
|
24
|
-
|
25
|
-
Expressions (expressions.py): Represent code constructs that evaluate to a value.
|
26
|
-
|
27
|
-
Identifier: Variable names, function names.
|
28
|
-
|
29
|
-
VariableReference: Usage of a variable.
|
30
|
-
|
31
|
-
AttributeAccess: Accessing attributes (e.g., motor.spin).
|
32
|
-
|
33
|
-
BinaryOperation: Operations like +, -, *, /, ==, and, or.
|
34
|
-
|
35
|
-
UnaryOperation: Operations like - (negation), not.
|
36
|
-
|
37
|
-
FunctionCall: Calling functions or methods.
|
38
|
-
|
39
|
-
KeywordArgument: Named arguments in function calls (e.g., speed=50).
|
40
|
-
|
41
|
-
Literals (literals.py): Represent constant values.
|
42
|
-
|
43
|
-
NumberLiteral: Integers and floats.
|
44
|
-
|
45
|
-
StringLiteral: Text strings.
|
46
|
-
|
47
|
-
BooleanLiteral: True or False.
|
48
|
-
|
49
|
-
NoneLiteral: The None value.
|
50
|
-
|
51
|
-
Statements (statements.py): Represent actions or control flow constructs.
|
52
|
-
|
53
|
-
ExpressionStatement: An expression used on its own line (e.g., a function call).
|
54
|
-
|
55
|
-
Assignment: Assigning a value to a variable (=).
|
56
|
-
|
57
|
-
IfStatement: Conditional execution (if/elif/else).
|
58
|
-
|
59
|
-
WhileLoop: Looping based on a condition.
|
60
|
-
|
61
|
-
ForLoop: Iterating over a sequence.
|
62
|
-
|
63
|
-
FunctionDefinition: Defining a function (def).
|
64
|
-
|
65
|
-
Argument: Parameters in a function definition.
|
66
|
-
|
67
|
-
ReturnStatement: Returning a value from a function.
|
68
|
-
|
69
|
-
BreakStatement, ContinueStatement: Loop control.
|
70
|
-
|
71
|
-
Operators (operators.py): Defines Operator enums used within BinaryOperation and UnaryOperation nodes. Includes mappings from Python operators.
|
72
|
-
|
73
|
-
VEX-Specific Nodes (vex_nodes.py): Subclasses of FunctionCall tailored to represent common VEX API patterns.
|
74
|
-
|
75
|
-
VexAPICall: Base class for VEX calls.
|
76
|
-
|
77
|
-
MotorControl: Calls related to motors (e.g., motor.spin).
|
78
|
-
|
79
|
-
SensorReading: Calls related to sensors (e.g., sensor.value).
|
80
|
-
|
81
|
-
TimingControl: Calls like wait.
|
82
|
-
|
83
|
-
DisplayOutput: Calls related to screen output (e.g., brain.screen.print).
|
84
|
-
|
85
|
-
Usage
|
86
|
-
|
87
|
-
These node classes are typically instantiated by the parser (vex_ast.parser) during the code parsing process. Visitors (vex_ast.visitors) then interact with these node objects to perform tasks.
|
1
|
+
AST Node Definitions (vex_ast.ast)
|
2
|
+
|
3
|
+
This directory defines the structure and types of nodes used in the Abstract Syntax Tree (AST) representation of VEX V5 Python code.
|
4
|
+
|
5
|
+
Purpose
|
6
|
+
|
7
|
+
The AST provides a structured, hierarchical representation of the source code, abstracting away the specific syntax details. This structure is the foundation for analysis, transformation, and interpretation of the code.
|
8
|
+
|
9
|
+
Core Concepts
|
10
|
+
|
11
|
+
Interfaces (interfaces.py): Defines the fundamental protocols (IAstNode, IExpression, IStatement, ILiteral, IVisitor) that all nodes and visitors adhere to. This ensures a consistent structure.
|
12
|
+
|
13
|
+
Base Classes (core.py): Provides abstract base classes (AstNode, Expression, Statement) that implement common functionality like location tracking and the basic accept method for the Visitor pattern. Program is the root node type.
|
14
|
+
|
15
|
+
Visitor Pattern: Each node implements an accept(visitor) method, allowing external IVisitor objects to operate on the AST without modifying the node classes themselves.
|
16
|
+
|
17
|
+
Child Nodes: Each node provides a get_children() method to facilitate traversal of the tree.
|
18
|
+
|
19
|
+
Source Location: Nodes can store optional SourceLocation information (from vex_ast.utils) linking them back to the original code.
|
20
|
+
|
21
|
+
Node Categories
|
22
|
+
|
23
|
+
The AST nodes are organized into logical categories:
|
24
|
+
|
25
|
+
Expressions (expressions.py): Represent code constructs that evaluate to a value.
|
26
|
+
|
27
|
+
Identifier: Variable names, function names.
|
28
|
+
|
29
|
+
VariableReference: Usage of a variable.
|
30
|
+
|
31
|
+
AttributeAccess: Accessing attributes (e.g., motor.spin).
|
32
|
+
|
33
|
+
BinaryOperation: Operations like +, -, *, /, ==, and, or.
|
34
|
+
|
35
|
+
UnaryOperation: Operations like - (negation), not.
|
36
|
+
|
37
|
+
FunctionCall: Calling functions or methods.
|
38
|
+
|
39
|
+
KeywordArgument: Named arguments in function calls (e.g., speed=50).
|
40
|
+
|
41
|
+
Literals (literals.py): Represent constant values.
|
42
|
+
|
43
|
+
NumberLiteral: Integers and floats.
|
44
|
+
|
45
|
+
StringLiteral: Text strings.
|
46
|
+
|
47
|
+
BooleanLiteral: True or False.
|
48
|
+
|
49
|
+
NoneLiteral: The None value.
|
50
|
+
|
51
|
+
Statements (statements.py): Represent actions or control flow constructs.
|
52
|
+
|
53
|
+
ExpressionStatement: An expression used on its own line (e.g., a function call).
|
54
|
+
|
55
|
+
Assignment: Assigning a value to a variable (=).
|
56
|
+
|
57
|
+
IfStatement: Conditional execution (if/elif/else).
|
58
|
+
|
59
|
+
WhileLoop: Looping based on a condition.
|
60
|
+
|
61
|
+
ForLoop: Iterating over a sequence.
|
62
|
+
|
63
|
+
FunctionDefinition: Defining a function (def).
|
64
|
+
|
65
|
+
Argument: Parameters in a function definition.
|
66
|
+
|
67
|
+
ReturnStatement: Returning a value from a function.
|
68
|
+
|
69
|
+
BreakStatement, ContinueStatement: Loop control.
|
70
|
+
|
71
|
+
Operators (operators.py): Defines Operator enums used within BinaryOperation and UnaryOperation nodes. Includes mappings from Python operators.
|
72
|
+
|
73
|
+
VEX-Specific Nodes (vex_nodes.py): Subclasses of FunctionCall tailored to represent common VEX API patterns.
|
74
|
+
|
75
|
+
VexAPICall: Base class for VEX calls.
|
76
|
+
|
77
|
+
MotorControl: Calls related to motors (e.g., motor.spin).
|
78
|
+
|
79
|
+
SensorReading: Calls related to sensors (e.g., sensor.value).
|
80
|
+
|
81
|
+
TimingControl: Calls like wait.
|
82
|
+
|
83
|
+
DisplayOutput: Calls related to screen output (e.g., brain.screen.print).
|
84
|
+
|
85
|
+
Usage
|
86
|
+
|
87
|
+
These node classes are typically instantiated by the parser (vex_ast.parser) during the code parsing process. Visitors (vex_ast.visitors) then interact with these node objects to perform tasks.
|
vex_ast/ast/__init__.py
CHANGED
@@ -1,75 +1,75 @@
|
|
1
|
-
"""Abstract Syntax Tree (AST) package for VEX code."""
|
2
|
-
|
3
|
-
# Core AST classes
|
4
|
-
from .interfaces import (
|
5
|
-
IAstNode, IExpression, IStatement, ILiteral, IIdentifier, IFunctionCall, IAssignment,
|
6
|
-
IVisitor, T_VisitorResult, AstNode
|
7
|
-
)
|
8
|
-
from .core import Expression, Statement, Program
|
9
|
-
from .expressions import (
|
10
|
-
Identifier, VariableReference, AttributeAccess,
|
11
|
-
BinaryOperation, UnaryOperation, FunctionCall, KeywordArgument
|
12
|
-
)
|
13
|
-
from .statements import (
|
14
|
-
ExpressionStatement, Assignment, Argument, FunctionDefinition,
|
15
|
-
IfStatement, WhileLoop, ForLoop, ReturnStatement,
|
16
|
-
BreakStatement, ContinueStatement
|
17
|
-
)
|
18
|
-
from .literals import (
|
19
|
-
Literal, NumberLiteral, StringLiteral, BooleanLiteral, NoneLiteral
|
20
|
-
)
|
21
|
-
from .operators import Operator
|
22
|
-
from .vex_nodes import (
|
23
|
-
VexAPICallType, VexAPICall, MotorControl, SensorReading,
|
24
|
-
TimingControl, DisplayOutput, create_vex_api_call,
|
25
|
-
create_vex_api_call_from_interface
|
26
|
-
)
|
27
|
-
from .validators import validate_vex_functions, VexFunctionValidator
|
28
|
-
from .navigator import AstNavigator
|
29
|
-
|
30
|
-
# Expose the navigator as a factory function
|
31
|
-
def create_navigator(root: IAstNode) -> AstNavigator:
|
32
|
-
"""Create an AST navigator for the given root node.
|
33
|
-
|
34
|
-
Args:
|
35
|
-
root: The root node of the AST
|
36
|
-
|
37
|
-
Returns:
|
38
|
-
An AST navigator for traversing and querying the AST
|
39
|
-
"""
|
40
|
-
return AstNavigator(root)
|
41
|
-
|
42
|
-
__all__ = [
|
43
|
-
# Interfaces
|
44
|
-
'IAstNode', 'IExpression', 'IStatement', 'ILiteral', 'IIdentifier',
|
45
|
-
'IFunctionCall', 'IAssignment', 'IVisitor', 'T_VisitorResult', 'AstNode',
|
46
|
-
|
47
|
-
# Core
|
48
|
-
'Expression', 'Statement', 'Program',
|
49
|
-
|
50
|
-
# Expressions
|
51
|
-
'Identifier', 'VariableReference', 'AttributeAccess',
|
52
|
-
'BinaryOperation', 'UnaryOperation', 'FunctionCall', 'KeywordArgument',
|
53
|
-
|
54
|
-
# Statements
|
55
|
-
'ExpressionStatement', 'Assignment', 'Argument', 'FunctionDefinition',
|
56
|
-
'IfStatement', 'WhileLoop', 'ForLoop', 'ReturnStatement',
|
57
|
-
'BreakStatement', 'ContinueStatement',
|
58
|
-
|
59
|
-
# Literals
|
60
|
-
'Literal', 'NumberLiteral', 'StringLiteral', 'BooleanLiteral', 'NoneLiteral',
|
61
|
-
|
62
|
-
# Operators
|
63
|
-
'Operator',
|
64
|
-
|
65
|
-
# VEX-specific
|
66
|
-
'VexAPICallType', 'VexAPICall', 'MotorControl', 'SensorReading',
|
67
|
-
'TimingControl', 'DisplayOutput', 'create_vex_api_call',
|
68
|
-
'create_vex_api_call_from_interface',
|
69
|
-
|
70
|
-
# Validators
|
71
|
-
'validate_vex_functions', 'VexFunctionValidator',
|
72
|
-
|
73
|
-
# Navigator
|
74
|
-
'AstNavigator', 'create_navigator',
|
1
|
+
"""Abstract Syntax Tree (AST) package for VEX code."""
|
2
|
+
|
3
|
+
# Core AST classes
|
4
|
+
from .interfaces import (
|
5
|
+
IAstNode, IExpression, IStatement, ILiteral, IIdentifier, IFunctionCall, IAssignment,
|
6
|
+
IVisitor, T_VisitorResult, AstNode
|
7
|
+
)
|
8
|
+
from .core import Expression, Statement, Program
|
9
|
+
from .expressions import (
|
10
|
+
Identifier, VariableReference, AttributeAccess,
|
11
|
+
BinaryOperation, UnaryOperation, FunctionCall, KeywordArgument
|
12
|
+
)
|
13
|
+
from .statements import (
|
14
|
+
ExpressionStatement, Assignment, Argument, FunctionDefinition,
|
15
|
+
IfStatement, WhileLoop, ForLoop, ReturnStatement,
|
16
|
+
BreakStatement, ContinueStatement
|
17
|
+
)
|
18
|
+
from .literals import (
|
19
|
+
Literal, NumberLiteral, StringLiteral, BooleanLiteral, NoneLiteral
|
20
|
+
)
|
21
|
+
from .operators import Operator
|
22
|
+
from .vex_nodes import (
|
23
|
+
VexAPICallType, VexAPICall, MotorControl, SensorReading,
|
24
|
+
TimingControl, DisplayOutput, create_vex_api_call,
|
25
|
+
create_vex_api_call_from_interface
|
26
|
+
)
|
27
|
+
from .validators import validate_vex_functions, VexFunctionValidator
|
28
|
+
from .navigator import AstNavigator
|
29
|
+
|
30
|
+
# Expose the navigator as a factory function
|
31
|
+
def create_navigator(root: IAstNode) -> AstNavigator:
|
32
|
+
"""Create an AST navigator for the given root node.
|
33
|
+
|
34
|
+
Args:
|
35
|
+
root: The root node of the AST
|
36
|
+
|
37
|
+
Returns:
|
38
|
+
An AST navigator for traversing and querying the AST
|
39
|
+
"""
|
40
|
+
return AstNavigator(root)
|
41
|
+
|
42
|
+
__all__ = [
|
43
|
+
# Interfaces
|
44
|
+
'IAstNode', 'IExpression', 'IStatement', 'ILiteral', 'IIdentifier',
|
45
|
+
'IFunctionCall', 'IAssignment', 'IVisitor', 'T_VisitorResult', 'AstNode',
|
46
|
+
|
47
|
+
# Core
|
48
|
+
'Expression', 'Statement', 'Program',
|
49
|
+
|
50
|
+
# Expressions
|
51
|
+
'Identifier', 'VariableReference', 'AttributeAccess',
|
52
|
+
'BinaryOperation', 'UnaryOperation', 'FunctionCall', 'KeywordArgument',
|
53
|
+
|
54
|
+
# Statements
|
55
|
+
'ExpressionStatement', 'Assignment', 'Argument', 'FunctionDefinition',
|
56
|
+
'IfStatement', 'WhileLoop', 'ForLoop', 'ReturnStatement',
|
57
|
+
'BreakStatement', 'ContinueStatement',
|
58
|
+
|
59
|
+
# Literals
|
60
|
+
'Literal', 'NumberLiteral', 'StringLiteral', 'BooleanLiteral', 'NoneLiteral',
|
61
|
+
|
62
|
+
# Operators
|
63
|
+
'Operator',
|
64
|
+
|
65
|
+
# VEX-specific
|
66
|
+
'VexAPICallType', 'VexAPICall', 'MotorControl', 'SensorReading',
|
67
|
+
'TimingControl', 'DisplayOutput', 'create_vex_api_call',
|
68
|
+
'create_vex_api_call_from_interface',
|
69
|
+
|
70
|
+
# Validators
|
71
|
+
'validate_vex_functions', 'VexFunctionValidator',
|
72
|
+
|
73
|
+
# Navigator
|
74
|
+
'AstNavigator', 'create_navigator',
|
75
75
|
]
|
vex_ast/ast/core.py
CHANGED
@@ -1,71 +1,71 @@
|
|
1
|
-
"""Core AST node implementations."""
|
2
|
-
|
3
|
-
from typing import Any, Dict, List, Optional, Union, cast
|
4
|
-
|
5
|
-
from .interfaces import AstNode, IAstNode, IExpression, IStatement, IVisitor, T_VisitorResult
|
6
|
-
from ..utils.source_location import SourceLocation
|
7
|
-
|
8
|
-
class Expression(AstNode):
|
9
|
-
"""Base class for expression nodes."""
|
10
|
-
|
11
|
-
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
12
|
-
"""Default implementation that defers to visitor."""
|
13
|
-
method_name = f"visit_{self.__class__.__name__.lower()}"
|
14
|
-
if hasattr(visitor, method_name):
|
15
|
-
return getattr(visitor, method_name)(self)
|
16
|
-
return visitor.visit_expression(self)
|
17
|
-
|
18
|
-
class Statement(AstNode):
|
19
|
-
"""Base class for statement nodes."""
|
20
|
-
|
21
|
-
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
22
|
-
"""Default implementation that defers to visitor."""
|
23
|
-
method_name = f"visit_{self.__class__.__name__.lower()}"
|
24
|
-
if hasattr(visitor, method_name):
|
25
|
-
return getattr(visitor, method_name)(self)
|
26
|
-
return visitor.visit_statement(self)
|
27
|
-
|
28
|
-
class Program(AstNode):
|
29
|
-
"""Root node of the AST, representing the entire program."""
|
30
|
-
|
31
|
-
_fields = ('body',)
|
32
|
-
|
33
|
-
def __init__(self, body: List[IStatement], location: Optional[SourceLocation] = None):
|
34
|
-
super().__init__(location)
|
35
|
-
self.body = body
|
36
|
-
|
37
|
-
# Set parent references
|
38
|
-
for statement in self.body:
|
39
|
-
if isinstance(statement, AstNode):
|
40
|
-
statement.set_parent(self)
|
41
|
-
|
42
|
-
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
43
|
-
"""Accept a visitor."""
|
44
|
-
return visitor.visit_program(self)
|
45
|
-
|
46
|
-
def get_children(self) -> List[IAstNode]:
|
47
|
-
"""Get child nodes."""
|
48
|
-
return cast(List[IAstNode], self.body)
|
49
|
-
|
50
|
-
def get_statements(self) -> List[IStatement]:
|
51
|
-
"""Get all statements in the program."""
|
52
|
-
return self.body
|
53
|
-
|
54
|
-
def add_statement(self, statement: IStatement) -> None:
|
55
|
-
"""Add a statement to the program."""
|
56
|
-
self.body.append(statement)
|
57
|
-
if isinstance(statement, AstNode):
|
58
|
-
statement.set_parent(self)
|
59
|
-
|
60
|
-
def insert_statement(self, index: int, statement: IStatement) -> None:
|
61
|
-
"""Insert a statement at a specific position."""
|
62
|
-
self.body.insert(index, statement)
|
63
|
-
if isinstance(statement, AstNode):
|
64
|
-
statement.set_parent(self)
|
65
|
-
|
66
|
-
def remove_statement(self, statement: IStatement) -> bool:
|
67
|
-
"""Remove a statement from the program."""
|
68
|
-
if statement in self.body:
|
69
|
-
self.body.remove(statement)
|
70
|
-
return True
|
71
|
-
return False
|
1
|
+
"""Core AST node implementations."""
|
2
|
+
|
3
|
+
from typing import Any, Dict, List, Optional, Union, cast
|
4
|
+
|
5
|
+
from .interfaces import AstNode, IAstNode, IExpression, IStatement, IVisitor, T_VisitorResult
|
6
|
+
from ..utils.source_location import SourceLocation
|
7
|
+
|
8
|
+
class Expression(AstNode):
|
9
|
+
"""Base class for expression nodes."""
|
10
|
+
|
11
|
+
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
12
|
+
"""Default implementation that defers to visitor."""
|
13
|
+
method_name = f"visit_{self.__class__.__name__.lower()}"
|
14
|
+
if hasattr(visitor, method_name):
|
15
|
+
return getattr(visitor, method_name)(self)
|
16
|
+
return visitor.visit_expression(self)
|
17
|
+
|
18
|
+
class Statement(AstNode):
|
19
|
+
"""Base class for statement nodes."""
|
20
|
+
|
21
|
+
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
22
|
+
"""Default implementation that defers to visitor."""
|
23
|
+
method_name = f"visit_{self.__class__.__name__.lower()}"
|
24
|
+
if hasattr(visitor, method_name):
|
25
|
+
return getattr(visitor, method_name)(self)
|
26
|
+
return visitor.visit_statement(self)
|
27
|
+
|
28
|
+
class Program(AstNode):
|
29
|
+
"""Root node of the AST, representing the entire program."""
|
30
|
+
|
31
|
+
_fields = ('body',)
|
32
|
+
|
33
|
+
def __init__(self, body: List[IStatement], location: Optional[SourceLocation] = None):
|
34
|
+
super().__init__(location)
|
35
|
+
self.body = body
|
36
|
+
|
37
|
+
# Set parent references
|
38
|
+
for statement in self.body:
|
39
|
+
if isinstance(statement, AstNode):
|
40
|
+
statement.set_parent(self)
|
41
|
+
|
42
|
+
def accept(self, visitor: IVisitor[T_VisitorResult]) -> T_VisitorResult:
|
43
|
+
"""Accept a visitor."""
|
44
|
+
return visitor.visit_program(self)
|
45
|
+
|
46
|
+
def get_children(self) -> List[IAstNode]:
|
47
|
+
"""Get child nodes."""
|
48
|
+
return cast(List[IAstNode], self.body)
|
49
|
+
|
50
|
+
def get_statements(self) -> List[IStatement]:
|
51
|
+
"""Get all statements in the program."""
|
52
|
+
return self.body
|
53
|
+
|
54
|
+
def add_statement(self, statement: IStatement) -> None:
|
55
|
+
"""Add a statement to the program."""
|
56
|
+
self.body.append(statement)
|
57
|
+
if isinstance(statement, AstNode):
|
58
|
+
statement.set_parent(self)
|
59
|
+
|
60
|
+
def insert_statement(self, index: int, statement: IStatement) -> None:
|
61
|
+
"""Insert a statement at a specific position."""
|
62
|
+
self.body.insert(index, statement)
|
63
|
+
if isinstance(statement, AstNode):
|
64
|
+
statement.set_parent(self)
|
65
|
+
|
66
|
+
def remove_statement(self, statement: IStatement) -> bool:
|
67
|
+
"""Remove a statement from the program."""
|
68
|
+
if statement in self.body:
|
69
|
+
self.body.remove(statement)
|
70
|
+
return True
|
71
|
+
return False
|