Skip to content

Commit 343d50b

Browse files
committed
new files for dynamic
1 parent a07caf1 commit 343d50b

File tree

5 files changed

+433
-0
lines changed

5 files changed

+433
-0
lines changed

interp_Cany.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from ast import *
2+
from interp_Ldyn import Tagged
3+
from interp_Llambda import ClosureTuple
4+
from interp_Clambda import InterpClambda
5+
from utils import *
6+
7+
class InterpCany(InterpClambda):
8+
9+
def interp_exp(self, e, env):
10+
match e:
11+
case Call(Name('make_any'), [value, tag]):
12+
v = self.interp_exp(value, env)
13+
t = self.interp_exp(tag, env)
14+
return Tagged(v, t)
15+
case Call(Name('exit'), []):
16+
trace('exiting!')
17+
exit(0)
18+
case TagOf(value):
19+
v = self.interp_exp(value, env)
20+
match v:
21+
case Tagged(val, tag):
22+
return tag
23+
case _:
24+
raise Exception('interp TagOf unexpected ' + repr(v))
25+
case ValueOf(value, typ):
26+
v = self.interp_exp(value, env)
27+
match v:
28+
case Tagged(val, tag):
29+
return val
30+
case _:
31+
raise Exception('interp ValueOf unexpected ' + repr(v))
32+
case Call(Name('any_tuple_load'), [tup, index]):
33+
tv = self.interp_exp(tup, env)
34+
n = self.interp_exp(index, env)
35+
match tv:
36+
case Tagged(v, tag):
37+
return v[n]
38+
case _:
39+
raise Exception('interp any_tuple_load unexpected ' + repr(tv))
40+
case Call(Name('any_tuple_store'), [tup, index, value]):
41+
tv = self.interp_exp(tup, env)
42+
n = self.interp_exp(index, env)
43+
val = self.interp_exp(value, env)
44+
match tv:
45+
case Tagged(v, tag):
46+
v[n] = val
47+
return None # ??
48+
case _:
49+
raise Exception('interp any_tuple_load unexpected ' + repr(tv))
50+
case Call(Name('any_len'), [value]):
51+
v = self.interp_exp(value, env)
52+
match v:
53+
case Tagged(value, tag):
54+
return len(value)
55+
case _:
56+
raise Exception('interp any_len unexpected ' + repr(v))
57+
case _:
58+
return super().interp_exp(e, env)

interp_Lany.py

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
from ast import *
2+
from interp_Lfun import Function
3+
from interp_Llambda import InterpLlambda, ClosureTuple
4+
from interp_Ldyn import Tagged
5+
from utils import *
6+
7+
class InterpLany(InterpLlambda):
8+
9+
def type_to_tag(self, typ):
10+
match typ:
11+
case FunctionType(params, rt):
12+
return 'function'
13+
case TupleType(fields):
14+
return 'tuple'
15+
case t if t == int:
16+
return 'int'
17+
case t if t == bool:
18+
return 'bool'
19+
case IntType():
20+
return 'int'
21+
case BoolType():
22+
return 'int'
23+
case _:
24+
raise Exception('type_to_tag unexpected ' + repr(typ))
25+
26+
def arity(self, v):
27+
match v:
28+
case Function(name, params, body, env):
29+
return len(params)
30+
case ClosureTuple(args, arity):
31+
return arity
32+
case _:
33+
raise Exception('Lany arity unexpected ' + repr(v))
34+
35+
def interp_exp(self, e, env):
36+
match e:
37+
case Inject(value, typ):
38+
v = self.interp_exp(value, env)
39+
return Tagged(v, self.type_to_tag(typ))
40+
case Project(value, typ):
41+
v = self.interp_exp(value, env)
42+
match v:
43+
case Tagged(val, tag) if self.type_to_tag(typ) == tag:
44+
return val
45+
case _:
46+
raise Exception('interp project to ' + repr(typ) \
47+
+ ' unexpected ' + repr(v))
48+
case Call(Name('any_tuple_load'), [tup, index]):
49+
tv = self.interp_exp(tup, env)
50+
n = self.interp_exp(index, env)
51+
match tv:
52+
case Tagged(v, tag):
53+
return v[n]
54+
case _:
55+
raise Exception('interp any_tuple_load unexpected ' + repr(tv))
56+
case Call(Name('any_tuple_store'), [tup, index, value]):
57+
tv = self.interp_exp(tup, env)
58+
n = self.interp_exp(index, env)
59+
val = self.interp_exp(value, env)
60+
match tv:
61+
case Tagged(v, tag):
62+
v[n] = val
63+
return None # ??
64+
case _:
65+
raise Exception('interp any_tuple_load unexpected ' + repr(tv))
66+
case Call(Name('any_len'), [value]):
67+
v = self.interp_exp(value, env)
68+
match v:
69+
case Tagged(value, tag):
70+
return len(value)
71+
case _:
72+
raise Exception('interp any_len unexpected ' + repr(v))
73+
case Call(Name('make_any'), [value, tag]):
74+
v = self.interp_exp(value, env)
75+
t = self.interp_exp(tag, env)
76+
return Tagged(v, t)
77+
case Call(Name('arity'), [fun]):
78+
f = self.interp_exp(fun, env)
79+
return self.arity(f)
80+
case Call(Name('exit'), []):
81+
trace('exiting!')
82+
exit(0)
83+
case TagOf(value):
84+
v = self.interp_exp(value, env)
85+
match v:
86+
case Tagged(val, tag):
87+
return tag
88+
case _:
89+
raise Exception('interp TagOf unexpected ' + repr(v))
90+
case ValueOf(value, typ):
91+
v = self.interp_exp(value, env)
92+
match v:
93+
case Tagged(val, tag):
94+
return val
95+
case _:
96+
raise Exception('interp ValueOf unexpected ' + repr(v))
97+
case AnnLambda(params, returns, body):
98+
return Function('lambda', [x for (x,t) in params], [Return(body)], env)
99+
case _:
100+
return super().interp_exp(e, env)

interp_Ldyn.py

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
from ast import *
2+
from interp_Lfun import Function
3+
from interp_Llambda import InterpLlambda
4+
from utils import *
5+
6+
@dataclass(eq=True)
7+
class Tagged(Value):
8+
value : Value
9+
tag : str
10+
__match_args__ = ("value", "tag")
11+
def __str__(self):
12+
return str(self.value)
13+
14+
# todo: refactor the primitive operations
15+
16+
class InterpLdyn(InterpLlambda):
17+
18+
def tag(self, v):
19+
if v is True or v is False:
20+
return Tagged(v, 'bool')
21+
elif isinstance(v, int):
22+
return Tagged(v, 'int')
23+
elif isinstance(v, Function):
24+
return Tagged(v, 'function')
25+
elif isinstance(v, list):
26+
return Tagged(v, 'tuple')
27+
elif isinstance(v, type(None)):
28+
return Tagged(v, 'none')
29+
else:
30+
raise Exception('tag: unexpected ' + repr(v))
31+
32+
def untag(self, v, expected_tag, ast):
33+
match v:
34+
case Tagged(val, tag):
35+
if tag != expected_tag:
36+
raise Exception('expected tag ' + expected_tag \
37+
+ ', not ' + ' ' + repr(v))
38+
return val
39+
case _:
40+
raise Exception('expected Tagged value with ' + expected_tag \
41+
+ ', not ' + ' ' + repr(v))
42+
43+
def apply_fun(self, fun, args, e):
44+
f = self.untag(fun, 'function', e)
45+
return super().apply_fun(f, args, e)
46+
47+
def interp_exp(self, e, env):
48+
match e:
49+
# Tag the values
50+
case Constant(n):
51+
return self.tag(super().interp_exp(e, env))
52+
case Tuple(es, Load()):
53+
return self.tag(super().interp_exp(e, env))
54+
case Lambda(params, body):
55+
return self.tag(super().interp_exp(e, env))
56+
case Call(Name('input_int'), []):
57+
return self.tag(super().interp_exp(e, env))
58+
59+
# Lint operations
60+
case BinOp(left, Add(), right):
61+
l = self.interp_exp(left, env); r = self.interp_exp(right, env)
62+
return self.tag(self.untag(l, 'int', e) + self.untag(r, 'int', e))
63+
case BinOp(left, Sub(), right):
64+
l = self.interp_exp(left, env); r = self.interp_exp(right, env)
65+
return self.tag(self.untag(l, 'int', e) - self.untag(r, 'int', e))
66+
case UnaryOp(USub(), e1):
67+
v = self.interp_exp(e1, env)
68+
return self.tag(- self.untag(v, 'int', e))
69+
70+
# Lif operations
71+
case IfExp(test, body, orelse):
72+
v = self.interp_exp(test, env)
73+
match self.untag(v, 'bool', e):
74+
case True:
75+
return self.interp_exp(body, env)
76+
case False:
77+
return self.interp_exp(orelse, env)
78+
case UnaryOp(Not(), e1):
79+
v = self.interp_exp(e1, env)
80+
return self.tag(not self.untag(v, 'bool', e))
81+
case BoolOp(And(), values):
82+
left = values[0]; right = values[1]
83+
l = self.interp_exp(left, env)
84+
match self.untag(l, 'bool', e):
85+
case True:
86+
return self.interp_exp(right, env)
87+
case False:
88+
return self.tag(False)
89+
case BoolOp(Or(), values):
90+
left = values[0]; right = values[1]
91+
l = self.interp_exp(left, env)
92+
match self.untag(l, 'bool', e):
93+
case True:
94+
return True
95+
case False:
96+
return self.interp_exp(right, env)
97+
case Compare(left, [cmp], [right]):
98+
l = self.interp_exp(left, env)
99+
r = self.interp_exp(right, env)
100+
if l.tag == r.tag:
101+
return self.tag(self.interp_cmp(cmp)(l.value, r.value))
102+
else:
103+
raise Exception('interp Compare unexpected ' \
104+
+ repr(l) + ' ' + repr(r))
105+
106+
# Ltup operations
107+
case Subscript(tup, index, Load()):
108+
t = self.interp_exp(tup, env)
109+
n = self.interp_exp(index, env)
110+
return self.untag(t, 'tuple', e)[self.untag(n, 'int', e)]
111+
case Call(Name('len'), [tup]):
112+
t = self.interp_exp(tup, env)
113+
return self.tag(len(self.untag(t, 'tuple', e)))
114+
115+
case _:
116+
return super().interp_exp(e, env)
117+
118+
def interp_stmts(self, ss, env):
119+
if len(ss) == 0:
120+
return
121+
match ss[0]:
122+
123+
# Lif statements
124+
case If(test, body, orelse):
125+
v = self.interp_exp(test, env)
126+
match self.untag(v, 'bool', ss[0]):
127+
case True:
128+
return self.interp_stmts(body + ss[1:], env)
129+
case False:
130+
return self.interp_stmts(orelse + ss[1:], env)
131+
132+
# Lwhile statements
133+
case While(test, body, []):
134+
while self.untag(self.interp_exp(test, env), 'bool', ss[0]):
135+
self.interp_stmts(body, env)
136+
return self.interp_stmts(ss[1:], env)
137+
138+
# Ltup statements
139+
case Assign([Subscript(tup, index)], value):
140+
tup = self.interp_exp(tup, env)
141+
index = self.interp_exp(index, env)
142+
tup_v = self.untag(tup, 'tuple', ss[0])
143+
index_v = self.untag(index, 'int', ss[0])
144+
tup_v[index_v] = self.interp_exp(value, env)
145+
return self.interp_stmts(ss[1:], env)
146+
147+
# override to tag the function
148+
case FunctionDef(name, params, bod, dl, returns, comment):
149+
if isinstance(params, ast.arguments):
150+
ps = [p.arg for p in params.args]
151+
else:
152+
ps = [x for (x,t) in params]
153+
env[name] = self.tag(Function(name, ps, bod, env))
154+
return self.interp_stmts(ss[1:], env)
155+
156+
case _:
157+
return super().interp_stmts(ss, env)
158+

type_check_Cany.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from type_check_Clambda import TypeCheckClambda
2+
from utils import *
3+
4+
class TypeCheckCany(TypeCheckClambda):
5+
6+
def type_check_exp(self, e, env):
7+
match e:
8+
case ValueOf(value, typ):
9+
self.type_check_exp(value, env)
10+
return typ
11+
case TagOf(value):
12+
t = self.type_check_exp(value, env)
13+
self.check_type_equal(t, AnyType(), e)
14+
return IntType()
15+
case Call(Name('any_tuple_load'), [tup, index]):
16+
t = self.type_check_exp(tup, env)
17+
self.check_type_equal(t, AnyType(), e)
18+
return AnyType()
19+
case Call(Name('any_tuple_store'), [tup, index, value]):
20+
t = self.type_check_exp(tup, env)
21+
self.check_type_equal(t, AnyType(), e)
22+
v = self.type_check_exp(value, env)
23+
self.check_type_equal(v, AnyType(), e)
24+
return type(None) # ??
25+
case Call(Name('any_len'), [tup]):
26+
t = self.type_check_exp(tup, env)
27+
self.check_type_equal(t, AnyType(), e)
28+
return IntType()
29+
case Call(Name('make_any'), [value, tag]):
30+
v = self.type_check_exp(value, env)
31+
t = self.type_check_exp(tag, env)
32+
self.check_type_equal(t, IntType(), e)
33+
return AnyType()
34+
case Call(Name('exit'), []):
35+
return Bottom()
36+
case Call(Name('arity'), [fun]):
37+
ty = self.type_check_exp(fun, env)
38+
match ty:
39+
case FunctionType(ps, rt):
40+
return IntType()
41+
case TupleType([FunctionType(ps,rs)]): # after closure conversion
42+
return IntType()
43+
case _:
44+
raise Exception('type_check_exp arity unexpected ' + repr(ty))
45+
case _:
46+
return super().type_check_exp(e, env)
47+

0 commit comments

Comments
 (0)