forked from IUCompilerCourse/python-student-support-code
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompiler.py
133 lines (111 loc) · 4.59 KB
/
compiler.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
import ast
from ast import *
from utils import *
from x86_ast import *
import os
from typing import List, Tuple, Set, Dict
Binding = Tuple[Name, expr]
Temporaries = List[Binding]
class Compiler:
############################################################################
# Remove Complex Operands
############################################################################
def rco_exp(self, e: expr, need_atomic : bool) -> Tuple[expr, Temporaries]:
match e:
case Constant(n):
return Constant(n), []
case Call(Name('input_int'),[]):
if need_atomic:
tmp = Name(generate_name('tmp'))
return tmp, [(tmp, Call(Name('input_int'),[]))]
else:
return Call(Name('input_int'),[]), []
case UnaryOp(USub(), exp):
(atm, temps) = self.rco_exp(exp, True)
usub = UnaryOp(USub(), atm)
if need_atomic:
tmp = Name(generate_name('tmp'))
return tmp, temps + [(tmp, usub)]
else:
return usub, temps
case BinOp(exp1, Add(), exp2):
(atm1, temps1) = self.rco_exp(exp1, True)
(atm2, temps2) = self.rco_exp(exp2, True)
add = BinOp(atm1, Add(), atm2)
if need_atomic:
tmp = Name(generate_name('tmp'))
return tmp, temps1 + temps2 + [(tmp, add)]
else:
return add, temps1 + temps2
case BinOp(exp1, Sub(), exp2):
(atm1, temps1) = self.rco_exp(exp1, True)
(atm2, temps2) = self.rco_exp(exp2, True)
sub = BinOp(atm1, Sub(), atm2)
if need_atomic:
tmp = Name(generate_name('tmp'))
return tmp, temps1 + temps2 + [(tmp, sub)]
else:
return sub, temps1 + temps2
case Name(var):
return Name(var), []
case _:
raise Exception('rco_exp unexpected ' + repr(e))
def rco_stmt(self, s: stmt) -> List[stmt]:
match s:
case Expr(Call(Name('print'), [exp])):
(atm, temps) = self.rco_exp(exp, True)
return [Assign([var], init) for (var,init) in temps] + [Expr(Call(Name('print'), [atm]))]
case Expr(exp) :
(atm, temps) = self.rco_exp(exp, False)
return [Assign([var], init) for (var,init) in temps]
case Assign([Name(var)], exp):
(atm, temps) = self.rco_exp(exp, False)
return [Assign([x], init) for (x,init) in temps] + [Assign([Name(var)], atm)]
case _:
raise Exception('rco_stmt not implemented')
def remove_complex_operands(self, p: Module) -> Module:
match p:
case Module(ss):
sss = [self.rco_stmt(s) for s in ss]
return Module(sum(sss, []))
raise Exception('remove_complex_operands not implemented')
############################################################################
# Select Instructions
############################################################################
def select_arg(self, e: expr) -> arg:
# YOUR CODE HERE
pass
def select_stmt(self, s: stmt) -> List[instr]:
# YOUR CODE HERE
pass
def select_instructions(self, p: Module) -> X86Program:
# YOUR CODE HERE
pass
############################################################################
# Assign Homes
############################################################################
def assign_homes_arg(self, a: arg, home: Dict[Variable, arg]) -> arg:
# YOUR CODE HERE
pass
def assign_homes_instr(self, i: instr,
home: Dict[Variable, arg]) -> instr:
# YOUR CODE HERE
pass
def assign_homes(self, p: X86Program) -> X86Program:
# YOUR CODE HERE
pass
############################################################################
# Patch Instructions
############################################################################
def patch_instr(self, i: instr) -> List[instr]:
# YOUR CODE HERE
pass
def patch_instructions(self, p: X86Program) -> X86Program:
# YOUR CODE HERE
pass
############################################################################
# Prelude & Conclusion
############################################################################
def prelude_and_conclusion(self, p: X86Program) -> X86Program:
# YOUR CODE HERE
pass