Skip to content

Commit a07caf1

Browse files
committed
updates for dynamic typing
1 parent 6afade2 commit a07caf1

18 files changed

+553
-344
lines changed

interp_Cfun.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def interp_exp(self, e, env):
3131
f = self.interp_exp(func, env)
3232
vs = [self.interp_exp(arg, env) for arg in args]
3333
return self.apply_fun(f, vs, e)
34-
case FunRef(id):
34+
case FunRef(id, arity):
3535
return env[id]
3636
case _:
3737
return super().interp_exp(e, env)

interp_Clambda.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,29 @@
11
from ast import *
22
from interp_Cfun import InterpCfun
3+
from interp_Llambda import ClosureTuple
34
from utils import *
5+
from interp_Lfun import Function
46

57
class InterpClambda(InterpCfun):
68

9+
def arity(self, v):
10+
match v:
11+
case Function(name, params, body, env):
12+
return len(params)
13+
case ClosureTuple(args, arity):
14+
return arity
15+
case _:
16+
raise Exception('Cany arity unexpected ' + repr(v))
17+
718
def interp_exp(self, e, env):
819
match e:
20+
case Call(Name('arity'), [fun]):
21+
f = self.interp_exp(fun, env)
22+
return self.arity(f)
23+
case Uninitialized(ty):
24+
return None
925
case AllocateClosure(length, typ, arity):
1026
array = [None] * length
11-
return array
27+
return ClosureTuple(array, arity)
1228
case _:
1329
return super().interp_exp(e, env)

interp_Lfun.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def interp_exp(self, e, env):
3232
f = self.interp_exp(func, env)
3333
vs = [self.interp_exp(arg, env) for arg in args]
3434
return self.apply_fun(f, vs, e)
35-
case FunRef(id):
35+
case FunRef(id, arity):
3636
return env[id]
3737
case _:
3838
return super().interp_exp(e, env)
@@ -43,21 +43,23 @@ def interp_stmts(self, ss, env):
4343
match ss[0]:
4444
case Return(value):
4545
return self.interp_exp(value, env)
46+
case FunctionDef(name, params, bod, dl, returns, comment):
47+
if isinstance(params, ast.arguments):
48+
ps = [p.arg for p in params.args]
49+
else:
50+
ps = [x for (x,t) in params]
51+
env[name] = Function(name, ps, bod, env)
52+
return self.interp_stmts(ss[1:], env)
4653
case _:
4754
return super().interp_stmts(ss, env)
48-
55+
4956
def interp(self, p):
5057
match p:
51-
case Module(defs):
58+
case Module(ss):
5259
env = {}
53-
for d in defs:
54-
match d:
55-
case FunctionDef(name, params, bod, dl, returns, comment):
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)
61-
self.apply_fun(env['main'], [], None)
60+
self.interp_stmts(ss, env)
61+
#trace('interp global env: ' + repr(env))
62+
if 'main' in env.keys():
63+
self.apply_fun(env['main'], [], None)
6264
case _:
6365
raise Exception('interp: unexpected ' + repr(p))

interp_Lif.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,14 @@ def interp_exp(self, e, env):
4747
l = self.interp_exp(left, env)
4848
r = self.interp_exp(right, env)
4949
return self.interp_cmp(cmp)(l, r)
50-
case Let(Name(x), rhs, body):
51-
v = self.interp_exp(rhs, env)
52-
new_env = dict(env)
53-
new_env[x] = v
54-
return self.interp_exp(body, new_env)
50+
# case Let(Name(x), rhs, body):
51+
# v = self.interp_exp(rhs, env)
52+
# new_env = dict(env)
53+
# new_env[x] = v
54+
# return self.interp_exp(body, new_env)
55+
case Begin(ss, e):
56+
self.interp_stmts(ss, env)
57+
return self.interp_exp(e, env)
5558
case _:
5659
return super().interp_exp(e, env)
5760

interp_Lint.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ def interp_stmts(self, ss, env):
5555
return
5656
match ss[0]:
5757
case Expr(Call(Name('print'), [arg])):
58-
print(self.interp_exp(arg, env), end='')
58+
val = self.interp_exp(arg, env)
59+
print(val, end='')
5960
return self.interp_stmts(ss[1:], env)
6061
case Expr(value):
6162
self.interp_exp(value, env)

interp_Llambda.py

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,46 @@
22
from interp_Lfun import InterpLfun, Function
33
from utils import *
44

5+
6+
class ClosureTuple:
7+
__match_args__ = ("args", "arity")
8+
def __init__(self, args, arity):
9+
self.args = args
10+
self.arity = arity
11+
def __repr__(self):
12+
return 'ClosureTuple(' + repr(self.args) + ', ' + repr(self.arity) + ')'
13+
def __getitem__(self, item):
14+
return self.args[item]
15+
def __setitem__(self, item, value):
16+
self.args[item] = value
17+
518
class InterpLlambda(InterpLfun):
619

20+
def arity(self, v):
21+
match v:
22+
case Function(name, params, body, env):
23+
return len(params)
24+
case ClosureTuple(args, arity):
25+
return arity
26+
case _:
27+
raise Exception('Llambda arity unexpected ' + repr(v))
28+
729
def interp_exp(self, e, env):
830
match e:
9-
case FunRefArity(id, arity):
31+
case Call(Name('arity'), [fun]):
32+
f = self.interp_exp(fun, env)
33+
return self.arity(f)
34+
case Uninitialized(ty):
35+
return None
36+
case FunRef(id, arity):
1037
return env[id]
1138
case Lambda(params, body):
1239
return Function('lambda', params, [Return(body)], env)
1340
case Closure(arity, args):
14-
return tuple([self.interp_exp(arg, env) for arg in args])
41+
return ClosureTuple([self.interp_exp(arg, env) for arg in args], arity)
1542
case AllocateClosure(length, typ, arity):
1643
array = [None] * length
17-
return array
44+
return ClosureTuple(array, arity)
1845
case _:
1946
return super().interp_exp(e, env)
2047

interp_Ltup.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@ def interp_exp(self, e, env):
2626
case Allocate(length, typ):
2727
array = [None] * length
2828
return array
29-
case Begin(ss, e):
30-
self.interp_stmts(ss, env)
31-
return self.interp_exp(e, env)
3229
case GlobalValue(name):
3330
return 0 # ???
3431
case _:

type_check_Cfun.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def check_type_equal(self, t1, t2, e):
2323

2424
def type_check_exp(self, e, env):
2525
match e:
26-
case FunRef(id):
26+
case FunRef(id, arity):
2727
return env[id]
2828
case Call(Name('input_int'), []):
2929
return super().type_check_exp(e, env)
@@ -55,6 +55,7 @@ def type_check_def(self, d, env):
5555
old_env = copy.deepcopy(new_env)
5656
for (l,ss) in blocks.items():
5757
self.type_check_stmts(ss, new_env)
58+
# trace('type_check_Cfun iterating ' + repr(new_env))
5859
if new_env == old_env:
5960
break
6061
# todo check return type

type_check_Cif.py

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from ast import *
2-
from utils import CProgram, Goto, trace, Bottom, Let
2+
from utils import CProgram, Goto, trace, Bottom, IntType, BoolType, Begin
33
import copy
44

55
class TypeCheckCif:
@@ -11,14 +11,23 @@ def check_type_equal(self, t1, t2, e):
1111
raise Exception('error: ' + repr(t1) + ' != ' + repr(t2) \
1212
+ ' in ' + repr(e))
1313

14+
def combine_types(self, t1, t2):
15+
match (t1, t2):
16+
case (Bottom(), _):
17+
return t2
18+
case (_, Bottom()):
19+
return t1
20+
case _:
21+
return t1
22+
1423
def type_check_atm(self, e, env):
1524
match e:
1625
case Name(id):
1726
return env.get(id, Bottom())
1827
case Constant(value) if isinstance(value, bool):
19-
return bool
28+
return BoolType()
2029
case Constant(value) if isinstance(value, int):
21-
return int
30+
return IntType()
2231
case _:
2332
raise Exception('error in type_check_atm, unexpected ' + repr(e))
2433

@@ -30,43 +39,47 @@ def type_check_exp(self, e, env):
3039
return self.type_check_atm(e, env)
3140
case IfExp(test, body, orelse):
3241
test_t = self.type_check_exp(test, env)
33-
self.check_type_equal(bool, test_t, test)
42+
self.check_type_equal(BoolType(), test_t, test)
3443
body_t = self.type_check_exp(body, env)
3544
orelse_t = self.type_check_exp(orelse, env)
3645
self.check_type_equal(body_t, orelse_t, e)
3746
return body_t
3847
case BinOp(left, op, right) if isinstance(op, Add) or isinstance(op, Sub):
3948
l = self.type_check_atm(left, env)
40-
self.check_type_equal(l, int, e)
49+
self.check_type_equal(l, IntType(), e)
4150
r = self.type_check_atm(right, env)
42-
self.check_type_equal(r, int, e)
43-
return int
51+
self.check_type_equal(r, IntType(), e)
52+
return IntType()
4453
case UnaryOp(USub(), v):
4554
t = self.type_check_atm(v, env)
46-
self.check_type_equal(t, int, e)
47-
return int
55+
self.check_type_equal(t, IntType(), e)
56+
return IntType()
4857
case UnaryOp(Not(), v):
4958
t = self.type_check_exp(v, env)
50-
self.check_type_equal(t, bool, e)
51-
return bool
52-
case Compare(left, [cmp], [right]) if isinstance(cmp, Eq) or isinstance(cmp, NotEq):
59+
self.check_type_equal(t, BoolType(), e)
60+
return BoolType()
61+
case Compare(left, [cmp], [right]) if isinstance(cmp, Eq) \
62+
or isinstance(cmp, NotEq):
5363
l = self.type_check_atm(left, env)
5464
r = self.type_check_atm(right, env)
5565
self.check_type_equal(l, r, e)
56-
return bool
66+
return BoolType()
5767
case Compare(left, [cmp], [right]):
5868
l = self.type_check_atm(left, env)
59-
self.check_type_equal(l, int, left)
69+
self.check_type_equal(l, IntType(), left)
6070
r = self.type_check_atm(right, env)
61-
self.check_type_equal(r, int, right)
62-
return bool
71+
self.check_type_equal(r, IntType(), right)
72+
return BoolType()
6373
case Call(Name('input_int'), []):
64-
return int
65-
case Let(Name(x), rhs, body):
66-
t = self.type_check_exp(rhs, env)
67-
new_env = dict(env)
68-
new_env[x] = t
69-
return self.type_check_exp(body, new_env)
74+
return IntType()
75+
# case Let(Name(x), rhs, body):
76+
# t = self.type_check_exp(rhs, env)
77+
# new_env = dict(env)
78+
# new_env[x] = t
79+
# return self.type_check_exp(body, new_env)
80+
case Begin(ss, e):
81+
self.type_check_stmts(ss, env)
82+
return self.type_check_exp(e, env)
7083
case _:
7184
raise Exception('error in type_check_exp, unexpected ' + repr(e))
7285

@@ -79,12 +92,14 @@ def type_check_stmt(self, s, env):
7992
case Assign([lhs], value):
8093
t = self.type_check_exp(value, env)
8194
if lhs.id in env:
82-
self.check_type_equal(env.get(lhs.id, Bottom()), t, s)
95+
lhs_ty = env.get(lhs.id, Bottom())
96+
self.check_type_equal(lhs_ty, t, s)
97+
env[lhs.id] = self.combine_types(t, lhs_ty)
8398
else:
8499
env[lhs.id] = t
85100
case Expr(Call(Name('print'), [arg])):
86101
t = self.type_check_exp(arg, env)
87-
self.check_type_equal(t, int, s)
102+
self.check_type_equal(t, IntType(), s)
88103
case Expr(value):
89104
self.type_check_exp(value, env)
90105
case If(Compare(left, [cmp], [right]), body, orelse):

type_check_Clambda.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
from utils import AllocateClosure
1+
from utils import AllocateClosure, Uninitialized
22
from type_check_Cfun import TypeCheckCfun
33

44
class TypeCheckClambda(TypeCheckCfun):
55

66
def type_check_exp(self, e, env):
77
match e:
8+
case Uninitialized(ty):
9+
return ty
810
case AllocateClosure(length, typ, arity):
911
return typ
1012
case _:

0 commit comments

Comments
 (0)