Skip to content

Commit ffc264c

Browse files
committed
support code updates
1 parent a7b3725 commit ffc264c

26 files changed

+527
-159
lines changed

Diff for: interp_Cfun.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ def interp_exp(self, e, env):
2525
match e:
2626
case Call(Name('input_int'), []):
2727
return super().interp_exp(e, env)
28+
case Call(Name('len'), [tup]):
29+
return super().interp_exp(e, env)
2830
case Call(func, args):
2931
f = self.interp_exp(func, env)
3032
vs = [self.interp_exp(arg, env) for arg in args]
@@ -38,8 +40,8 @@ def interp_stmts(self, ss, env):
3840
if len(ss) == 0:
3941
raise Exception('interp_stmts function ended without return')
4042
match ss[0]:
41-
case Return(value):
42-
return self.interp_exp(value, env)
43+
case TailCall(func, args):
44+
return self.interp_exp(Call(func, args), env)
4345
case _:
4446
return super().interp_stmts(ss, env)
4547

@@ -50,10 +52,9 @@ def interp(self, p):
5052
for d in defs:
5153
match d:
5254
case FunctionDef(name, params, blocks, dl, returns, comment):
53-
env[name] = Function(name, [p.arg for p in params.args],
54-
blocks, env)
55+
env[name] = Function(name, [x for (x,t) in params], blocks, env)
5556
self.blocks = {}
5657
self.apply_fun(env['main'], [], None)
5758
case _:
5859
raise Exception('interp: unexpected ' + repr(p))
59-
60+

Diff for: interp_Cif.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ def interp(self, p):
2121
env = {}
2222
self.blocks = blocks
2323
self.interp_stmts(blocks[label_name('start')], env)
24-
24+

Diff for: interp_Clambda.py

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from ast import *
2+
from interp_Cfun import InterpCfun
3+
from utils import *
4+
5+
class InterpClambda(InterpCfun):
6+
7+
def interp_exp(self, e, env):
8+
match e:
9+
case AllocateClosure(length, typ, arity):
10+
array = [None] * length
11+
return array
12+
case _:
13+
return super().interp_exp(e, env)

Diff for: interp_Ctup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,4 @@ def interp_stmts(self, ss, env):
3838
tup[index] = self.interp_exp(value, env)
3939
return self.interp_stmts(ss[1:], env)
4040
case _:
41-
return super().interp_stmts(ss, env)
41+
return super().interp_stmts(ss, env)

Diff for: interp_Lfun.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def apply_fun(self, fun, args, e):
2626

2727
def interp_exp(self, e, env):
2828
match e:
29-
case Call(Name('input_int'), []):
29+
case Call(Name(f), args) if (f == 'input_int') or (f == 'len') or (f == 'print'):
3030
return super().interp_exp(e, env)
3131
case Call(func, args):
3232
f = self.interp_exp(func, env)
@@ -53,8 +53,11 @@ def interp(self, p):
5353
for d in defs:
5454
match d:
5555
case FunctionDef(name, params, bod, dl, returns, comment):
56-
env[name] = Function(name, [p.arg for p in params.args],
57-
bod, env)
56+
if isinstance(params, ast.arguments):
57+
ps = [p.arg for p in params.args]
58+
else:
59+
ps = [x for (x,t) in params]
60+
env[name] = Function(name, ps, bod, env)
5861
self.apply_fun(env['main'], [], None)
5962
case _:
60-
raise Exception('interp: unexpected ' + repr(p))
63+
raise Exception('interp: unexpected ' + repr(p))

Diff for: interp_Lif.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,4 @@ def interp_stmts(self, ss, env):
6767
return self.interp_stmts(orelse + ss[1:], env)
6868
case _:
6969
return super().interp_stmts(ss, env)
70-
70+

Diff for: interp_Lint.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,4 @@ def interp(self, p):
7575
ast1_1 = BinOp(read, Add(), neg_eight)
7676
pr = Expr(Call(Name('print'), [ast1_1]))
7777
p = Module([pr])
78-
interp(p)
78+
interp(p)

Diff for: interp_Llambda.py

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from ast import *
2+
from interp_Lfun import InterpLfun, Function
3+
from utils import *
4+
5+
class InterpLlambda(InterpLfun):
6+
7+
def interp_exp(self, e, env):
8+
match e:
9+
case FunRefArity(id, arity):
10+
return env[id]
11+
case Lambda(params, body):
12+
return Function('lambda', params, [Return(body)], env)
13+
case Closure(arity, args):
14+
return tuple([self.interp_exp(arg, env) for arg in args])
15+
case AllocateClosure(length, typ, arity):
16+
array = [None] * length
17+
return array
18+
case _:
19+
return super().interp_exp(e, env)
20+
21+
def interp_stmts(self, ss, env):
22+
if len(ss) == 0:
23+
return
24+
match ss[0]:
25+
case AnnAssign(lhs, typ, value, simple):
26+
env[lhs.id] = self.interp_exp(value, env)
27+
return self.interp_stmts(ss[1:], env)
28+
case _:
29+
return super().interp_stmts(ss, env)
30+

Diff for: interp_Ltup.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ def interp_cmp(self, cmp):
1414
def interp_exp(self, e, env):
1515
match e:
1616
case Tuple(es, Load()):
17-
return tuple([self.interp_exp(e, env) for e in es])
17+
# use a list for mutability
18+
return [self.interp_exp(e, env) for e in es]
1819
case Subscript(tup, index, Load()):
1920
t = self.interp_exp(tup, env)
2021
n = self.interp_exp(index, env)
@@ -53,4 +54,4 @@ def interp_stmts(self, ss, env):
5354
pr = Expr(Call(Name('print'), [t1_at_0]))
5455
p = Module([pr])
5556
InterpLtup().interp(p)
56-
57+

Diff for: interp_Lvar.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,4 @@ def interp(self, p):
3535
pr = Expr(Call(Name('print'), [ast1_1]))
3636
p = Module([pr])
3737
interp = InterpLvar()
38-
interp.interp_Lvar(p)
38+
interp.interp_Lvar(p)

Diff for: interp_Lwhile.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ def interp_stmts(self, ss, env):
1414
return self.interp_stmts(ss[1:], env)
1515
case _:
1616
return super().interp_stmts(ss, env)
17-
17+

Diff for: interp_Pwhile.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ def interp_stmts(self, ss, env):
1414
return self.interp_stmts(ss[1:], env)
1515
case _:
1616
return super().interp_stmts(ss, env)
17-
17+

Diff for: type_check_Cfun.py

+28-31
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,41 @@
11
from ast import *
22
from utils import *
3-
from type_check_Ctup import check_type_equal, TypeCheckCtup
3+
from type_check_Ctup import TypeCheckCtup
44
import copy
55

66
class TypeCheckCfun(TypeCheckCtup):
7-
8-
# def parse_type_annot(self, annot):
9-
# match annot:
10-
# case Name(id):
11-
# if id == 'int':
12-
# return int
13-
# elif id == 'bool':
14-
# return bool
15-
# else:
16-
# raise Exception('parse_type_annot: unexpected ' + repr(annot))
17-
# case TupleType(ts):
18-
# return TupleType([self.parse_type_annot(t) for t in ts])
19-
# case FunctionType(ps, rt):
20-
# return FunctionType([self.parse_type_annot(t) for t in ps],
21-
# self.parse_type_annot(rt))
22-
# case Subscript(Name('Callable'), Tuple([ps, rt])):
23-
# return FunctionType([self.parse_type_annot(t) for t in ps.elts],
24-
# self.parse_type_annot(rt))
25-
# case Subscript(Name('tuple'), Tuple(ts)):
26-
# return TupleType([self.parse_type_annot(t) for t in ts])
27-
# case _:
28-
# raise Exception('parse_type_annot: unexpected ' + repr(annot))
29-
7+
8+
def check_type_equal(self, t1, t2, e):
9+
if t1 == Bottom() or t2 == Bottom():
10+
return
11+
match t1:
12+
case FunctionType(ps1, rt1):
13+
match t2:
14+
case FunctionType(ps2, rt2):
15+
for (p1,p2) in zip(ps1, ps2):
16+
self.check_type_equal(p1, p2, e)
17+
self.check_type_equal(rt1, rt2, e)
18+
case _:
19+
raise Exception('error: ' + repr(t1) + ' != ' + repr(t2) \
20+
+ ' in ' + repr(e))
21+
case _:
22+
super().check_type_equal(t1, t2, e)
23+
3024
def type_check_exp(self, e, env):
3125
match e:
3226
case FunRef(id):
3327
return env[id]
3428
case Call(Name('input_int'), []):
3529
return super().type_check_exp(e, env)
30+
case Call(Name('len'), [tup]):
31+
return super().type_check_exp(e, env)
3632
case Call(func, args):
3733
func_t = self.type_check_exp(func, env)
3834
args_t = [self.type_check_exp(arg, env) for arg in args]
3935
match func_t:
4036
case FunctionType(params_t, return_t):
4137
for (arg_t, param_t) in zip(args_t, params_t):
42-
check_type_equal(param_t, arg_t, e)
38+
self.check_type_equal(param_t, arg_t, e)
4339
return return_t
4440
case Bottom():
4541
return Bottom()
@@ -68,14 +64,14 @@ def type_check_def(self, d, env):
6864
case _:
6965
raise Exception('type_check_def: unexpected ' + repr(d))
7066

71-
def type_check_stmts(self, ss, env):
72-
if len(ss) == 0:
73-
return
74-
match ss[0]:
67+
def type_check_stmt(self, s, env):
68+
match s:
7569
case Return(value):
76-
return self.type_check_exp(value, env)
70+
self.type_check_exp(value, env)
71+
case TailCall(func, args):
72+
self.type_check_exp(Call(func, args), env)
7773
case _:
78-
return super().type_check_stmts(ss, env)
74+
super().type_check_stmt(s, env)
7975

8076
def type_check(self, p):
8177
match p:
@@ -90,3 +86,4 @@ def type_check(self, p):
9086
self.type_check_def(d, env)
9187
case _:
9288
raise Exception('type_check: unexpected ' + repr(p))
89+

Diff for: type_check_Cif.py

+23-23
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
from utils import CProgram, Goto, trace, Bottom, Let
33
import copy
44

5-
def check_type_equal(t1, t2, e):
5+
class TypeCheckCif:
6+
7+
def check_type_equal(self, t1, t2, e):
68
if t1 == Bottom() or t2 == Bottom():
7-
pass
9+
pass
810
elif t1 != t2:
9-
raise Exception('error: ' + repr(t1) + ' != ' + repr(t2) \
10-
+ ' in ' + repr(e))
11-
12-
class TypeCheckCif:
11+
raise Exception('error: ' + repr(t1) + ' != ' + repr(t2) \
12+
+ ' in ' + repr(e))
1313

1414
def type_check_atm(self, e, env):
1515
match e:
@@ -30,35 +30,35 @@ def type_check_exp(self, e, env):
3030
return self.type_check_atm(e, env)
3131
case IfExp(test, body, orelse):
3232
test_t = self.type_check_exp(test, env)
33-
check_type_equal(bool, test_t, test)
33+
self.check_type_equal(bool, test_t, test)
3434
body_t = self.type_check_exp(body, env)
3535
orelse_t = self.type_check_exp(orelse, env)
36-
check_type_equal(body_t, orelse_t, e)
36+
self.check_type_equal(body_t, orelse_t, e)
3737
return body_t
3838
case BinOp(left, op, right) if isinstance(op, Add) or isinstance(op, Sub):
3939
l = self.type_check_atm(left, env)
40-
check_type_equal(l, int, e)
40+
self.check_type_equal(l, int, e)
4141
r = self.type_check_atm(right, env)
42-
check_type_equal(r, int, e)
42+
self.check_type_equal(r, int, e)
4343
return int
4444
case UnaryOp(USub(), v):
4545
t = self.type_check_atm(v, env)
46-
check_type_equal(t, int, e)
46+
self.check_type_equal(t, int, e)
4747
return int
4848
case UnaryOp(Not(), v):
4949
t = self.type_check_exp(v, env)
50-
check_type_equal(t, bool, e)
50+
self.check_type_equal(t, bool, e)
5151
return bool
5252
case Compare(left, [cmp], [right]) if isinstance(cmp, Eq) or isinstance(cmp, NotEq):
5353
l = self.type_check_atm(left, env)
5454
r = self.type_check_atm(right, env)
55-
check_type_equal(l, r, e)
55+
self.check_type_equal(l, r, e)
5656
return bool
5757
case Compare(left, [cmp], [right]):
5858
l = self.type_check_atm(left, env)
59-
check_type_equal(l, int, left)
59+
self.check_type_equal(l, int, left)
6060
r = self.type_check_atm(right, env)
61-
check_type_equal(r, int, right)
61+
self.check_type_equal(r, int, right)
6262
return bool
6363
case Call(Name('input_int'), []):
6464
return int
@@ -70,23 +70,27 @@ def type_check_exp(self, e, env):
7070
case _:
7171
raise Exception('error in type_check_exp, unexpected ' + repr(e))
7272

73+
def type_check_stmts(self, ss, env):
74+
for s in ss:
75+
self.type_check_stmt(s, env)
76+
7377
def type_check_stmt(self, s, env):
7478
match s:
7579
case Assign([lhs], value):
7680
t = self.type_check_exp(value, env)
7781
if lhs.id in env:
78-
check_type_equal(env.get(lhs.id, Bottom()), t, s)
82+
self.check_type_equal(env.get(lhs.id, Bottom()), t, s)
7983
else:
8084
env[lhs.id] = t
8185
case Expr(Call(Name('print'), [arg])):
8286
t = self.type_check_exp(arg, env)
83-
check_type_equal(t, int, s)
87+
self.check_type_equal(t, int, s)
8488
case Expr(value):
8589
self.type_check_exp(value, env)
8690
case If(Compare(left, [cmp], [right]), body, orelse):
8791
left_t = self.type_check_atm(left, env)
8892
right_t = self.type_check_atm(right, env)
89-
check_type_equal(left_t, right_t, s) # not quite strict enough
93+
self.check_type_equal(left_t, right_t, s) # not quite strict enough
9094
self.type_check_stmts(body, env)
9195
self.type_check_stmts(orelse, env)
9296
case Goto(label):
@@ -96,10 +100,6 @@ def type_check_stmt(self, s, env):
96100
case _:
97101
raise Exception('error in type_check_stmt, unexpected' + repr(s))
98102

99-
def type_check_stmts(self, ss, env):
100-
for s in ss:
101-
self.type_check_stmt(s, env)
102-
103103
def type_check(self, p):
104104
match p:
105105
case CProgram(body):
@@ -112,4 +112,4 @@ def type_check(self, p):
112112
break
113113
p.var_types = env
114114
case _:
115-
raise Exception('error in type_check, unexpected ' + repr(p))
115+
raise Exception('error in type_check, unexpected ' + repr(p))

Diff for: type_check_Clambda.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from utils import AllocateClosure
2+
from type_check_Cfun import TypeCheckCfun
3+
4+
class TypeCheckClambda(TypeCheckCfun):
5+
6+
def type_check_exp(self, e, env):
7+
match e:
8+
case AllocateClosure(length, typ, arity):
9+
return typ
10+
case _:
11+
return super().type_check_exp(e, env)
12+

0 commit comments

Comments
 (0)