-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcse.py
More file actions
361 lines (356 loc) · 14.6 KB
/
Copy pathcse.py
File metadata and controls
361 lines (356 loc) · 14.6 KB
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
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
from cse_structs import Base, control_stk, stack_stk, parsing_env, control_structures, add_in_built_to_env, in_built_functions, print_control_structures
from vocabulary import is_binary_operator as isBOp, is_unary_operator as isUOp
from nodes import ast_stack as ast_bu # or wherever your AST stack is defined
env_count = 0
def add_func_to_control(prev, number):
temp_env = Base("environment", prev=prev)
control_stk.append(temp_env)
stack_stk.append(temp_env)
parsing_env.append(temp_env)
for item in control_structures[number]:
control_stk.append(item)
def pre_order_traversal(root, environment):
global env_count
if root.label == "lambda":
env_count += 1
lambda_base = Base("lambda", arg_int=env_count)
control_structures.append([])
pre_order_traversal(root.children[1], env_count)
# Arguments: can be a single identifier or a list
if root.children[0].label != ",":
sliced = root.children[0].label[4:-1]
# print(Base("identifier", sliced))
lambda_base.children.append(Base("identifier", sliced))
else:
for child in root.children[0].children:
sliced = child.label[4:-1]
lambda_base.children.append(Base("identifier", sliced))
control_structures[environment].append(lambda_base)
elif root.label == "->":
env_count += 1
control_structures[environment].append(Base("delta", arg_int=env_count))
control_structures.append([])
pre_order_traversal(root.children[1], env_count)
env_count += 1
control_structures[environment].append(Base("delta", arg_int=env_count))
control_structures.append([])
pre_order_traversal(root.children[2], env_count)
control_structures[environment].append(Base("beta"))
pre_order_traversal(root.children[0], environment)
else:
if root.label.startswith("<"):
if root.label[1] == "I":
if root.label[2] == "N":
num = int(root.label[5:-1])
control_structures[environment].append(Base("integer", arg_int=num))
else:
sliced = root.label[4:-1]
control_structures[environment].append(Base("identifier", sliced))
else:
sliced = root.label[6:-2]
control_structures[environment].append(Base("string", sliced))
elif isBOp(root.label) or isUOp(root.label):
control_structures[environment].append(Base("operator", root.label))
elif root.label in ("true", "false"):
control_structures[environment].append(Base("boolean", root.label))
elif root.label == "Ystar":
control_structures[environment].append(Base("ystar"))
elif root.label == "tau":
control_structures[environment].append(Base("tau", arg_int=len(root.children)))
elif root.label == "gamma":
control_structures[environment].append(Base("gamma"))
elif root.label == "dummy":
control_structures[environment].append(Base("dummy"))
elif root.label == "nil":
control_structures[environment].append(Base("tuple"))
for child in root.children:
pre_order_traversal(child, environment)
print
def rules(type_):
if type_ == "integer" or type_ == "boolean" or type_ == "string" or type_ == "tuple":
stack_stk.append(control_stk[-1])
control_stk.pop()
elif type_ == "operator":
op = control_stk[-1].arg_str
control_stk.pop()
if op == "eq":
a = stack_stk[-1]
stack_stk.pop()
b = stack_stk[-1]
stack_stk.pop()
if a.type == "integer" and b.type == "integer":
if a.arg_int == b.arg_int:
stack_stk.append(Base("boolean", "true"))
else:
stack_stk.append(Base("boolean", "false"))
elif a.type == "boolean" and b.type == "boolean":
if a.arg_str == b.arg_str:
stack_stk.append(Base("boolean", "true"))
else:
stack_stk.append(Base("boolean", "false"))
elif a.type == "string" and b.type == "string":
if a.arg_str == b.arg_str:
stack_stk.append(Base("boolean", "true"))
else:
stack_stk.append(Base("boolean", "false"))
else:
print(f"Expect an integer or boolean or string pairs with {op}")
raise RuntimeError("Error")
elif op == "ne":
a = stack_stk[-1]
stack_stk.pop()
b = stack_stk[-1]
stack_stk.pop()
if a.type == "integer" and b.type == "integer":
if a.arg_int == b.arg_int:
stack_stk.append(Base("boolean", "false"))
else:
stack_stk.append(Base("boolean", "true"))
elif a.type == "boolean" and b.type == "boolean":
if a.arg_str == b.arg_str:
stack_stk.append(Base("boolean", "false"))
else:
stack_stk.append(Base("boolean", "true"))
elif a.type == "string" and b.type == "string":
if a.arg_str == b.arg_str:
stack_stk.append(Base("boolean", "false"))
else:
stack_stk.append(Base("boolean", "true"))
else:
print(f"Expect an integer or boolean or string pairs with {op}")
raise RuntimeError("Error")
elif op in ("+", "-", "*", "/", "**", "gr", "ge", "ls", "le"):
if stack_stk[-1].type != "integer":
print(f"Expect an integer with {op}")
raise RuntimeError("Error")
a = stack_stk[-1].arg_int
stack_stk.pop()
if stack_stk[-1].type != "integer":
print(f"Expect an integer with {op}")
raise RuntimeError("Error")
b = stack_stk[-1].arg_int
stack_stk.pop()
if op == "+":
stack_stk.append(Base("integer", arg_int = a + b))
elif op == "-":
stack_stk.append(Base("integer", arg_int = a - b))
elif op == "*":
stack_stk.append(Base("integer", arg_int = a * b))
elif op == "/":
stack_stk.append(Base("integer", arg_int = a // b))
elif op == "**":
stack_stk.append(Base("integer", arg_int = pow(a, b)))
elif op == "gr":
if a > b:
stack_stk.append(Base("boolean", "true"))
else:
stack_stk.append(Base("boolean", "false"))
elif op == "ge":
if a >= b:
stack_stk.append(Base("boolean", "true"))
else:
stack_stk.append(Base("boolean", "false"))
elif op == "ls":
if a < b:
stack_stk.append(Base("boolean", "true"))
else:
stack_stk.append(Base("boolean", "false"))
else: # op == "le"
if a <= b:
stack_stk.append(Base("boolean", "true"))
else:
stack_stk.append(Base("boolean", "false"))
elif op == "neg":
if stack_stk[-1].type != "integer":
print(f"Expect an integer with {op}")
raise RuntimeError("Error")
a = stack_stk[-1].arg_int
stack_stk.pop()
stack_stk.append(Base("integer", arg_int = -a))
elif op == "not":
if stack_stk[-1].type != "boolean":
print(f"Expect a boolean with {op}")
raise RuntimeError("Error")
a = stack_stk[-1].arg_str
stack_stk.pop()
if a == "true":
stack_stk.append(Base("boolean", "false"))
else:
stack_stk.append(Base("boolean", "true"))
elif op in ("or", "&"):
if stack_stk[-1].type != "boolean":
print(f"Expect a boolean with {op}")
raise RuntimeError("Error")
a = stack_stk[-1].arg_str
stack_stk.pop()
if stack_stk[-1].type != "boolean":
print(f"Expect a boolean with {op}")
raise RuntimeError("Error")
b = stack_stk[-1].arg_str
stack_stk.pop()
if op == "or":
if a == "true" or b == "true":
stack_stk.append(Base("boolean", "true"))
else:
stack_stk.append(Base("boolean", "false"))
else: # (op == "&")
if a == "true" and b == "true":
stack_stk.append(Base("boolean", "true"))
else:
stack_stk.append(Base("boolean", "false"))
elif op == "aug":
if stack_stk[-1].type != "tuple":
print(f"Cannot append to {stack_stk[-1].type}")
raise RuntimeError("Error")
lst = stack_stk[-1]
stack_stk.pop()
lst.children.append(stack_stk[-1])
stack_stk.pop()
stack_stk.append(lst)
elif type_ == "lambda":
stack_stk.append(control_stk[-1])
control_stk.pop()
stack_stk[-1].prev = parsing_env[-1]
elif type_ == "gamma":
# print(stack_stk[-1])
if stack_stk[-1].type == "lambda":
# print("Lambda found")
func = stack_stk[-1]
control_stk.pop()
stack_stk.pop()
func_args = stack_stk[-1]
stack_stk.pop()
if func.arg_int is not None and func.arg_int >= 0:
add_func_to_control(func.prev, func.arg_int)
if len(func.children) > 1:
if len(func_args.children) != len(func.children):
raise RuntimeError("Insufficient arguments")
for i in range(len(func_args.children)):
temp = Base("identifier", func.children[i].arg_str)
temp.prev = func_args.children[i]
parsing_env[-1].children.append(temp)
else:
parsing_env[-1].children.append(Base("identifier", func.children[0].arg_str, prev = func_args))
# print(Base("identifier", func.children[0].arg_str, prev = func_args))
else:
in_built_functions(func, func_args)
elif stack_stk[-1].type == "tuple":
control_stk.pop()
lst = stack_stk[-1]
stack_stk.pop()
index = stack_stk[-1].arg_int
# print(stack_stk[-1])
stack_stk.pop()
# print(index)
# print("/n")
if (index > len(lst.children)) or (index <= 0):
print(f"Index:{index} is out of bound in ")
# print_Base(lst) # Assuming you have a function to print the Base structure
raise RuntimeError("Error")
stack_stk.append(lst.children[index - 1])
elif stack_stk[-1].type == "ystar":
control_stk.pop()
stack_stk.pop()
lambda_ = stack_stk[-1]
stack_stk.pop()
eta = Base("eta")
eta.prev = lambda_.prev
eta.children = lambda_.children
eta.arg_int = lambda_.arg_int
stack_stk.append(eta)
elif stack_stk[-1].type == "eta":
control_stk.append(Base("gamma"))
lambda_ = Base("lambda")
lambda_.prev = stack_stk[-1].prev
lambda_.children = stack_stk[-1].children
lambda_.arg_int = stack_stk[-1].arg_int
stack_stk.append(lambda_)
elif type_ == "environment":
returning = stack_stk[-1]
stack_stk.pop()
if stack_stk[-1] == control_stk[-1]:
control_stk.pop()
stack_stk.pop()
parsing_env.pop()
stack_stk.append(returning)
else:
print("Error with environment Base")
raise RuntimeError("Error")
elif type_ == "identifier":
env = parsing_env[-1]
value = None
found = False
while True:
for child in env.children:
if child.arg_str == control_stk[-1].arg_str:
found = True
if child.prev :
value = child.prev
else:
child.type = "lambda"
value = child
# print(child)
break
if found:
break
else:
env = env.prev
if env is None:
break
if not found:
print(f"Identifier {control_stk[-1].arg_str} not found")
raise RuntimeError("Error")
else:
stack_stk.append(value)
control_stk.pop()
elif type_ == "delta":
temp = control_stk[-1]
control_stk.pop()
for item in control_structures[temp.arg_int]:
control_stk.append(item)
elif type_ == "tau":
lst = Base("tuple")
for _ in range(control_stk[-1].arg_int):
lst.children.append(stack_stk[-1])
stack_stk.pop()
stack_stk.append(lst)
control_stk.pop()
elif type_ == "ystar":
stack_stk.append(control_stk[-1])
control_stk.pop()
elif type_ == "beta":
if stack_stk[-1].arg_str == "true":
control_stk.pop()
control_stk.pop()
stack_stk.pop()
elif stack_stk[-1].arg_str == "false":
control_stk.pop()
temp = control_stk[-1]
control_stk.pop()
control_stk.pop()
control_stk.append(temp)
stack_stk.pop()
else:
print("Expect a boolean")
raise RuntimeError("Error")
else:
print(f"Unknown type {type_}")
raise RuntimeError("Error")
def cse():
control_structures.append([])
pre_order_traversal(ast_bu[-1], 0)
parsing_env.append(Base("environment"))
parsing_env[-1].prev = None
add_in_built_to_env(parsing_env[-1])
add_func_to_control(parsing_env[-1], 0)
# print(control_stk[-1])
while len(control_stk) > 1:
the_type = control_stk[-1].type
rules(the_type)
# if stack_stk and control_stk and stack_stk[-1] != control_stk[-1]:
# print("Run time Error")
# raise Exception("Run time Error")
# if stack_stk:
# temp = stack_stk.pop()
# print("Final result:", temp)
# print_control_structures()