-
Notifications
You must be signed in to change notification settings - Fork 0
/
generator.py
125 lines (118 loc) · 5.7 KB
/
generator.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
class Generator:
def __init__(self, ir):
self.ir = ir
self.reg_cnt = 1
self.prefix = 2
self.width = 10
self.code = self.generate()
def generate(self):
code = []
for c in self.ir:
if c[1] is None:
if c[0][:4] == "goto": # Jump
code.append(
f"{' ' * self.prefix}{'JUMP':<{self.width}} {' ' * self.width} {c[0][5:]:<{self.width}}")
else: # Label
code.append(c[0])
else:
if c[1]:
bt = c[1].get_bt()
bt.value = 1
self.count_register(bt)
code.extend(self.create_code(c[0], bt))
return code
def create_code(self, ir, node):
code = []
nid = f"Reg#{node.value}"
if node.children:
left = node.children[0]
right = node.children[1]
lid = f"Reg#{left.value}"
rid = f"Reg#{right.value}"
if not left.children:
if node.key != "=":
code.extend(self.create_code("", left))
code.extend(self.create_code("", right))
if node.key == "+":
code.append(
f"{' ' * self.prefix}{'ADD':<{self.width}} {nid:<{self.width}} {lid:<{self.width}} {rid:<{self.width}}")
elif node.key == "*":
code.append(
f"{' ' * self.prefix}{'MUL':<{self.width}} {nid:<{self.width}} {lid:<{self.width}} {rid:<{self.width}}")
elif node.key == "=":
code.append(
f"{' ' * self.prefix}{'ST':<{self.width}} {rid:<{self.width}} {left.key:<{self.width}}")
else:
code.append(
f"{' ' * self.prefix}{'LT':<{self.width}} {nid:<{self.width}} {lid:<{self.width}} {rid:<{self.width}}")
code.append(" JUMPT {}, {}".format(nid, ir.split("goto")[-1][1:]))
code.append(
f"{' ' * self.prefix}{'JUMPT':<{self.width}} {nid:<{self.width}} {ir.split('goto')[-1][1:]:<{self.width}}")
elif not right.children:
code.extend(self.create_code("", left))
if node.key == "+":
code.append(
f"{' ' * self.prefix}{'ADD':<{self.width}} {nid:<{self.width}} {lid:<{self.width}} {rid:<{self.width}}")
elif node.key == "*":
code.append(
f"{' ' * self.prefix}{'MUL':<{self.width}} {nid:<{self.width}} {lid:<{self.width}} {rid:<{self.width}}")
elif node.key == "=":
code.append(
f"{' ' * self.prefix}{'ST':<{self.width}} {rid:<{self.width}} {left.key:<{self.width}}")
else:
code.append(
f"{' ' * self.prefix}{'LT':<{self.width}} {nid:<{self.width}} {rid:<{self.width}} {lid:<{self.width}}")
code.append(
f"{' ' * self.prefix}{'JUMPT':<{self.width}} {nid:<{self.width}} {ir.split('goto')[-1][1:]:<{self.width}}")
else:
code.extend(self.create_code("", left))
code.extend(self.create_code("", right))
if node.key == "+":
code.append(
f"{' ' * self.prefix}{'ADD':<{self.width}} {nid:<{self.width}} {lid:<{self.width}} {rid:<{self.width}}")
elif node.key == "*":
code.append(
f"{' ' * self.prefix}{'MUL':<{self.width}} {nid:<{self.width}} {lid:<{self.width}} {rid:<{self.width}}")
elif node.key == "=":
code.append(
f"{' ' * self.prefix}{'ST':<{self.width}} {rid:<{self.width}} {left.key:<{self.width}}")
else:
code.append(
f"{' ' * self.prefix}{'LT':<{self.width}} {nid:<{self.width}} {lid:<{self.width}} {rid:<{self.width}}")
code.append(
f"{' ' * self.prefix}{'JUMPT':<{self.width}} {nid:<{self.width}} {ir.split('goto')[-1][1:]:<{self.width}}")
elif ir[:4] == "EXIT":
code.append(
f"{' ' * self.prefix}{'LD':<{self.width}} {'rax':<{self.width}} {ir.split()[1]:<{self.width}}")
elif str(node.value).isdigit():
code.append(
f"{' ' * self.prefix}{'LD':<{self.width}} {'Reg#'+str(node.value):<{self.width}} {node.key:<{self.width}}")
return code
def count_register(self, node):
if node.children:
left = node.children[0]
right = node.children[1]
if node.key == "=":
right.value = node.value
self.count_register(right)
elif not right.children:
left.value = node.value
right.value = node.value + 1
self.reg_cnt = max(self.reg_cnt, right.value)
self.count_register(left)
elif not left.children:
left.value = node.value + 1
right.value = node.value
self.reg_cnt = max(self.reg_cnt, left.value)
self.count_register(right)
else:
left.value = node.value
right.value = node.value + 1
self.reg_cnt = max(self.reg_cnt, right.value)
self.count_register(left)
self.count_register(right)
def write_code(self, file):
for c in self.code:
file.write(f"{c}\n")
file.write(f"\nUsed Register Count: {self.reg_cnt}")
file.close()