-
Notifications
You must be signed in to change notification settings - Fork 0
/
node.py
223 lines (192 loc) · 7.02 KB
/
node.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
from lexer import LexerToken, TokenType
from enum import Enum, auto
class NodeType(Enum):
Empty = auto()
BinOp = auto()
Number = auto()
String = auto()
UnaryOp = auto()
Block = auto()
Assign = auto()
Variable = auto()
Type = auto()
Declare = auto()
Call = auto()
Import = auto()
While = auto()
For = auto()
IfStatement = auto()
Try = auto()
ArgumentList = auto()
SplatArgument = auto()
FunctionReturn = auto()
FunctionExpression = auto()
Macro = auto()
Mixin = auto()
ArrayExpression = auto()
ObjectExpression = auto()
MemberExpression = auto()
ArrayAccessExpression = auto()
class AstNode():
location = (0, 0)
def __init__(self, type, token):
self.type = type
self.token = token
self.location = token.location
@property
def this_object(self):
return self
def __str__(self):
try:
return "AstNode[{0}, {1}]".format(self.type.name, self.token)
except:
return "AstNode[{0}]".format(self.type.name)
def __repr__(self):
return self.__str__()
class NodeNone(AstNode):
def __init__(self, token):
AstNode.__init__(self, NodeType.Empty, token)
# Binary op node; LEFT [+-*/] RIGHT
class NodeBinOp(AstNode):
def __init__(self, left, token, right):
AstNode.__init__(self, NodeType.BinOp, token)
self.left = left
self.token = token
self.right = right
class NodeNumber(AstNode):
def __init__(self, token):
AstNode.__init__(self, NodeType.Number, token)
self.token = token
# int(..., 0) for guessing hexadecimal etc.
if '.' in token.value:
self.value = float(token.value)
else:
self.value = int(token.value, 0)
class NodeString(AstNode):
def __init__(self, token):
AstNode.__init__(self, NodeType.String, token)
self.value = str(token.value)[1:-1]
# Unary node; switches signage for values, '!' operator
class NodeUnaryOp(AstNode):
def __init__(self, token, expression):
AstNode.__init__(self, NodeType.UnaryOp, token)
self.token = token
self.expression = expression
# Block node; parent to multiple nodes
class NodeBlock(AstNode):
def __init__(self, token):
AstNode.__init__(self, NodeType.Block, token)
self.children = []
# Type node; Holds type info for variable
class NodeVarType(AstNode):
def __init__(self, token):
AstNode.__init__(self, NodeType.Type, token)
self.token = token
@property
def is_type_type(self):
return self.token.value == 'type'
# Declare node; declare variable or function
class NodeDeclare(AstNode):
def __init__(self, type, name, value, allow_casting=False):
AstNode.__init__(self, NodeType.Declare, name)
self.type_node = type
self.name = name
self.value = value
self.allow_casting = allow_casting
class NodeImport(AstNode):
def __init__(self, filename, source_location):
AstNode.__init__(self, NodeType.Import, filename)
self.children = []
self.source_location = source_location
class NodeWhile(AstNode):
def __init__(self, expr, block, token):
AstNode.__init__(self, NodeType.While, token)
self.block = block
self.expr = expr
class NodeFor(AstNode):
def __init__(self, var_token, expr, block, token):
AstNode.__init__(self, NodeType.For, token)
self.var_token = var_token
self.block = block
self.expr = expr
class NodeCall(AstNode):
def __init__(self, lhs, argument_list):
AstNode.__init__(self, NodeType.Call, lhs.token)
self.lhs = lhs
self.argument_list = argument_list
# Assignment node; Var = Value
class NodeAssign(AstNode):
def __init__(self, lhs, value):
AstNode.__init__(self, NodeType.Assign, value)
self.lhs = lhs
self.value = value
# Variable node; request value of variable
class NodeVariable(AstNode):
def __init__(self, token, allow_casting=False):
AstNode.__init__(self, NodeType.Variable, token)
self.token = token
self.value = token.value
self.allow_casting = allow_casting
class NodeIfStatement(AstNode):
def __init__(self, expr, block, else_block, token):
AstNode.__init__(self, NodeType.IfStatement, token)
self.expr = expr
self.block = block
self.else_block = else_block
class NodeTryCatch(AstNode):
def __init__(self, block, catch_block, expr, else_block, finally_block, token, variable):
AstNode.__init__(self, NodeType.Try, token)
self.block = block
self.catch_block = catch_block
self.expr = expr
self.else_block = else_block
self.finally_block = finally_block
self.variable = variable
class NodeArgumentList(AstNode):
def __init__(self, arguments, token):
AstNode.__init__(self, NodeType.ArgumentList, token)
self.arguments = arguments
class NodeSplatArgument(AstNode):
def __init__(self, expr, token):
AstNode.__init__(self, NodeType.SplatArgument, token)
self.expr = expr
class NodeFunctionExpression(AstNode):
def __init__(self, argument_list, block):
AstNode.__init__(self, NodeType.FunctionExpression, block)
self.argument_list = argument_list
self.block = block
class NodeFunctionReturn(AstNode):
def __init__(self, value_node, token):
AstNode.__init__(self, NodeType.FunctionReturn, token)
self.value_node = value_node
class NodeMacro(AstNode):
def __init__(self, expr, token):
AstNode.__init__(self, NodeType.Macro, token)
self.expr = expr
class NodeMixin(AstNode):
def __init__(self, tokens, token):
AstNode.__init__(self, NodeType.Mixin, token)
self.tokens = tokens
class NodeArrayExpression(AstNode):
def __init__(self, members, token, is_dictionary=False):
# members are var decls
AstNode.__init__(self, NodeType.ArrayExpression, token)
self.members = members
self.is_dictionary = is_dictionary
class NodeObjectExpression(AstNode):
def __init__(self, members):
# members are var decls
self.type = NodeType.ObjectExpression
self.members = members
class NodeMemberExpression(AstNode):
def __init__(self, lhs, identifier, token):
self.type = NodeType.MemberExpression
self.lhs = lhs
self.identifier = identifier
self.token = token
class NodeArrayAccessExpression(AstNode):
def __init__(self, lhs, access_expr, token):
self.type = NodeType.ArrayAccessExpression
self.lhs = lhs
self.access_expr = access_expr
self.token = token