-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathIR_nodes.py
294 lines (241 loc) · 7.54 KB
/
IR_nodes.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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
from utils.random_util import RandomUtil
from utils.graph_util import *
from IR_nodes import *
import copy
random_util = RandomUtil(123)
class IRGraphNode:
def __init__(self, lua_node):
self.IR_graph = None
self.id = -1
self.lua_node = lua_node
if lua_node:
self.name = lua_node._name
self.name_extra = ''
self.parent = None
self.children = []
self.contains_async = False
def __copy__(self):
cls = self.__class__
new_instance = cls.__new__(cls)
for attr, value in self.__dict__.items():
if isinstance(value, list):
setattr(new_instance, attr, copy.deepcopy(value))
else:
setattr(new_instance, attr, value)
new_instance.IR_graph = None
new_instance.id = -1
new_instance.lua_node = self.lua_node
new_instance.name = self.name
new_instance.parent = None
new_instance.children = []
return new_instance
# def __copy__(self):
# cls = self.__class__
# result = cls.__new__(cls)
# result.IR_graph = None
# result.id = -1
# result.lua_node = self.lua_node
# result.name = self.name
# result.parent = None
# result.children = []
# return result
def add_child(self, child):
child.parent = self
self.children.append(child)
def add_children(self, children):
for child in children:
child.parent = self
self.children.extend(children)
def remove_child(self, removed_child):
self.children = [child for child in self.children if child is not removed_child]
def remove_children(self, removed_children):
self.children = [child for child in self.children if child not in removed_children]
'''
################################################
REGULAR IR NODES
################################################
'''
'''
Regular graph nodes are any sort of exeuction that does not introduce differing levels of heirarchy or asynchronous calls
and do not require any modification
'''
class RegularIRGraphNode(IRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
class FunctionIRGraphNode(RegularIRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
class LocalFunctionIRGraphNode(RegularIRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
'''
Local assignments
'''
class LocalAssignIRGraphNode(RegularIRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
'''
Global assignments
'''
class GlobalAssignIRGraphNode(RegularIRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
'''
Semicolons
'''
class SemicolonIRGraphNode(RegularIRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
'''
Do-end blocks are typically used to introduce stricter scoping, and they do introduce differing levels of heirarchy--
but given that all variables will be converted to global variables anyways it doesn't matter.
'''
class DoIRGraphNode(RegularIRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
'''
################################################
ASYNC IR NODES
################################################
'''
'''
Asynchronous graph nodes
'''
class AsyncIRGraphNode(IRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
self.name = lua_node._name + ' (A)'
self.contains_async = True
'''
Asynchronous function calling
'''
class AsyncCallIRGraphNode(AsyncIRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
'''
Asynchronous assignments
'''
class AsyncAssignIRGraphNode(AsyncIRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
'''
################################################
CONTROL STRUCTURES IR NODES
################################################
'''
class ControlStructureIRGraphNode(IRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
'''
Conditional graph nodes (children to generated branch nodes)
'''
class ConditionalIRGraphNode(ControlStructureIRGraphNode):
def __init__(self, lua_node, name=""):
super().__init__(lua_node)
if name != "": self.name = name
class BreakIRGraphNode(ControlStructureIRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
class ReturnIRGraphNode(ControlStructureIRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
class GotoIRGraphNode(ControlStructureIRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
class LabelIRGraphNode(ControlStructureIRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
'''
################################################
LOOP IR NODES
################################################
'''
class LoopIRGraphNode(IRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
'''
Lua first tests the while condition; if the condition is false, then the loop ends;
otherwise, Lua executes the body of the loop and repeats the process.
'''
class WhileIRGraphNode(LoopIRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
'''
A repeat-until statement repeats its body until its condition is true.
The test is done after the body, so the body is always executed at least once.
'''
class RepeatIRGraphNode(LoopIRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
'''
The generic for loop allows you to traverse all values returned by an iterator function.
'''
class ForinIRGraphNode(LoopIRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
'''
The numeric for loop works as usual.
All three expressions in the declaration of the for loop are evaluated once, before the loop starts.
'''
class FornumIRGraphNode(LoopIRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
'''
################################################
COMPILATION GENERATED IR NODES
################################################
'''
class GeneratedIRGraphNode(IRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
'''
Helper node for statements with bodies
'''
class GeneratedBlockIRGraphNode(IRGraphNode):
def __init__(self, lua_node=None):
super().__init__(lua_node)
self.name = "Block (G)"
'''
Links IR graphs together, dst_node will be the root node of another IR graph
'''
class GeneratedLinkIRGraphNode(GeneratedIRGraphNode):
def __init__(self, linked_graph, async_link):
super().__init__(lua_node=None)
self.async_link = async_link
self.generated_link_name = random_util.generate_function_name()
self.name = "Link " + ("(A) " if self.async_link else "") + self.generated_link_name[5:10] + " → " + linked_graph.generated_name[5:10] + " (G)"
self.linked_graph = linked_graph
if self.linked_graph is None:
print("here")
exit()
'''
Placeholder for a new function node
'''
class GeneratedFunctionIRGraphNode(GeneratedIRGraphNode):
def __init__(self, generated_function_name):
super().__init__(lua_node=None)
self.generated_function_name = generated_function_name
self.name = "Function " + generated_function_name[5:10] + " (G)"
'''
Intermediate reprsentation for conditionals. This node will contain each elseif/else statement.
'''
class GeneratedBranchIRGraphNode(GeneratedIRGraphNode):
def __init__(self, lua_node):
super().__init__(lua_node)
self.name = 'Branch (G)'
self.else_statement_present = False
'''
Placeholder for new else node
'''
class GeneratedConditionalElseIRGraphNode(GeneratedIRGraphNode):
def __init__(self):
super().__init__(lua_node=None)
self.name = "Else (G)"
'''
Placeholder for setting the event pointer
'''
class GeneratedSetEventPointerNode(GeneratedIRGraphNode):
def __init__(self, pointer):
super().__init__(lua_node=None)
self.name = "SetEventPointer " + pointer[5:10]
self.pointer = pointer