Skip to content

Commit 8f54efc

Browse files
committed
student code
1 parent cf4b208 commit 8f54efc

17 files changed

+2283
-0
lines changed

interpRvar.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from utils import input_int
2+
3+
class InterpRVar:
4+
5+
def interp_exp(env, e):
6+
match e:
7+
case Constant(n):
8+
return n
9+
case Call(Name('input_int'), []):
10+
return input_int()
11+
case UnaryOp(USub(), e1):
12+
return - interp_exp(e1)
13+
case BinOp(e1, Add(), e2):
14+
return interp_exp(e1) + interp_exp(e2)
15+
case _:
16+
return False
17+
18+
def interp_stmt(s):
19+
match s:
20+
case Call(Name('print'), [e]):
21+
print(interp_exp(e))
22+
case Expr(e):
23+
interp_exp(e)
24+
case _:
25+
return
26+
27+
def interp_Rint(p):
28+
match p:
29+
case Module(body):
30+
for s in body:
31+
interp_stmt(s)
32+
33+
if __name__ == "__main__":
34+
eight = Constant(8)
35+
neg_eight = UnaryOp(USub(), eight)
36+
read = Call(Name('input_int'), [])
37+
ast1_1 = BinOp(read, Add(), neg_eight)
38+
pr = Call(Name('print'), [ast1_1])
39+
p = Module([pr])
40+
interp_Rint(p)

interp_Cif.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from ast import *
2+
from interp_Pif import InterpPif
3+
from utils import *
4+
5+
class InterpCif(InterpPif):
6+
7+
def interp_stmts(self, ss, env):
8+
if len(ss) == 0:
9+
return
10+
match ss[0]:
11+
case Return(value):
12+
return self.interp_exp(value, env)
13+
case Goto(label):
14+
return self.interp_stmts(self.CFG[label], env)
15+
case _:
16+
return super().interp_stmts(ss, env)
17+
18+
def interp_C(self, p):
19+
match p:
20+
case CProgram(cfg):
21+
env = {}
22+
self.CFG = cfg
23+
self.interp_stmts(cfg[label_name('start')], env)
24+

interp_Pif.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
from ast import *
2+
from interp_Pvar import InterpPvar
3+
from utils import *
4+
5+
class InterpPif(InterpPvar):
6+
7+
def interp_cmp(self, cmp):
8+
match cmp:
9+
case Lt():
10+
return lambda x, y: x < y
11+
case LtE():
12+
return lambda x, y: x <= y
13+
case Gt():
14+
return lambda x, y: x > y
15+
case GtE():
16+
return lambda x, y: x >= y
17+
case Eq():
18+
return lambda x, y: x == y
19+
case NotEq():
20+
return lambda x, y: x != y
21+
22+
def interp_exp(self, e, env):
23+
match e:
24+
case IfExp(test, body, orelse):
25+
match self.interp_exp(test, env):
26+
case True:
27+
return self.interp_exp(body, env)
28+
case False:
29+
return self.interp_exp(orelse, env)
30+
case BinOp(left, Sub(), right):
31+
l = self.interp_exp(left, env)
32+
r = self.interp_exp(right, env)
33+
return l - r
34+
case UnaryOp(Not(), v):
35+
return not self.interp_exp(v, env)
36+
case BoolOp(And(), values):
37+
left = values[0]; right = values[1]
38+
match self.interp_exp(left, env):
39+
case True:
40+
return self.interp_exp(right, env)
41+
case False:
42+
return False
43+
case BoolOp(Or(), values):
44+
left = values[0]; right = values[1]
45+
match self.interp_exp(left, env):
46+
case True:
47+
return True
48+
case False:
49+
return self.interp_exp(right, env)
50+
case Compare(left, [cmp], [right]):
51+
l = self.interp_exp(left, env)
52+
r = self.interp_exp(right, env)
53+
return self.interp_cmp(cmp)(l, r)
54+
case Let(Name(x), rhs, body):
55+
v = self.interp_exp(rhs, env)
56+
new_env = dict(env)
57+
new_env[x] = v
58+
return self.interp_exp(body, new_env)
59+
case _:
60+
return super().interp_exp(e, env)
61+
62+
def interp_stmts(self, ss, env):
63+
if len(ss) == 0:
64+
return
65+
match ss[0]:
66+
case If(test, body, orelse):
67+
match self.interp_exp(test, env):
68+
case True:
69+
return self.interp_stmts(body + ss[1:], env)
70+
case False:
71+
return self.interp_stmts(orelse + ss[1:], env)
72+
case _:
73+
return super().interp_stmts(ss, env)
74+

interp_Pint.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from ast import *
2+
from utils import input_int
3+
4+
def interp_exp(e):
5+
match e:
6+
case BinOp(left, Add(), right):
7+
l = interp_exp(left)
8+
r = interp_exp(right)
9+
return l + r
10+
case UnaryOp(USub(), v):
11+
return - interp_exp(v)
12+
case Constant(value):
13+
return value
14+
case Call(Name('input_int'), []):
15+
return int(input())
16+
17+
def interp_stmt(s):
18+
match s:
19+
case Expr(Call(Name('print'), [arg])):
20+
print(interp_exp(arg))
21+
case Expr(value):
22+
interp_exp(value)
23+
24+
def interp_P(p):
25+
match p:
26+
case Module(body):
27+
for s in body:
28+
interp_stmt(s)
29+
30+
if __name__ == "__main__":
31+
eight = Constant(8)
32+
neg_eight = UnaryOp(USub(), eight)
33+
read = Call(Name('input_int'), [])
34+
ast1_1 = BinOp(read, Add(), neg_eight)
35+
pr = Expr(Call(Name('print'), [ast1_1]))
36+
p = Module([pr])
37+
interp_Pint(p)

interp_Pvar.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from ast import *
2+
from utils import input_int
3+
4+
class InterpPvar:
5+
def interp_exp(self, e, env):
6+
match e:
7+
case BinOp(left, Add(), right):
8+
l = self.interp_exp(left, env)
9+
r = self.interp_exp(right, env)
10+
return l + r
11+
case UnaryOp(USub(), v):
12+
return - self.interp_exp(v, env)
13+
case Name(id):
14+
return env[id]
15+
case Constant(value):
16+
return value
17+
case Call(Name('input_int'), []):
18+
return int(input())
19+
case _:
20+
raise Exception('error in InterpPvar.interp_exp, unhandled ' + repr(e))
21+
22+
def interp_stmts(self, ss, env):
23+
if len(ss) == 0:
24+
return
25+
match ss[0]:
26+
case Assign([lhs], value):
27+
env[lhs.id] = self.interp_exp(value, env)
28+
return self.interp_stmts(ss[1:], env)
29+
case Expr(Call(Name('print'), [arg])):
30+
print(self.interp_exp(arg, env), end='')
31+
return self.interp_stmts(ss[1:], env)
32+
case Expr(value):
33+
self.interp_exp(value, env)
34+
return self.interp_stmts(ss[1:], env)
35+
case _:
36+
raise Exception('error in InterpPvar.interp_stmt, unhandled ' + repr(ss[0]))
37+
38+
def interp_P(self, p):
39+
match p:
40+
case Module(body):
41+
self.interp_stmts(body, {})
42+
43+
if __name__ == "__main__":
44+
eight = Constant(8)
45+
neg_eight = UnaryOp(USub(), eight)
46+
read = Call(Name('input_int'), [])
47+
ast1_1 = BinOp(read, Add(), neg_eight)
48+
pr = Expr(Call(Name('print'), [ast1_1]))
49+
p = Module([pr])
50+
interp = InterpPvar()
51+
interp.interp_Pvar(p)
Binary file not shown.
11.4 KB
Binary file not shown.
Binary file not shown.

interp_x86/convert_x86.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Convert from the x86 AST classes defined in utils.py into the parse
2+
# tree format used by the interpreter.
3+
4+
from lark import Tree
5+
from ast import Name, Constant
6+
from x86_ast import *
7+
from utils import label_name
8+
9+
def convert_int(value):
10+
if value >= 0:
11+
return Tree('int_a', [Tree('int_a', [value])])
12+
else:
13+
return Tree('neg_a',[Tree('int_a', [- value])])
14+
15+
def convert_arg(arg):
16+
match arg:
17+
case Reg(id):
18+
return Tree('reg_a', [id])
19+
case Variable(id):
20+
return Tree('var_a', [id])
21+
case Immediate(value):
22+
return convert_int(value)
23+
case Deref(reg, offset):
24+
return Tree('mem_a', [convert_int(offset), reg])
25+
case ByteReg(id):
26+
return Tree('reg_a', [id])
27+
case _:
28+
raise Exception('convert_arg: unhandled ' + repr(arg))
29+
30+
def convert_instr(instr):
31+
match instr:
32+
case Instr(instr, args):
33+
return Tree(instr, [convert_arg(arg) for arg in args])
34+
case Callq(func, args):
35+
return Tree('callq', [func])
36+
case Jump(label):
37+
return Tree('jmp', [label])
38+
case JumpIf(cc, label):
39+
return Tree('j' + cc, [label])
40+
case _:
41+
raise Exception('error in convert_instr, unhandled ' + repr(instr))
42+
43+
def convert_program(p):
44+
if isinstance(p.body, list):
45+
main_instrs = [convert_instr(instr) for instr in p.body]
46+
main_block = Tree('block', [label_name('main')] + main_instrs)
47+
return Tree('prog', [main_block])
48+
elif isinstance(p.body, dict):
49+
blocks = []
50+
for (l, ss) in p.body.items():
51+
blocks.append(Tree('block',
52+
[l] + [convert_instr(instr) for instr in ss]))
53+
return Tree('prog', blocks)
54+

0 commit comments

Comments
 (0)