forked from IUCompilerCourse/python-student-support-code
-
Notifications
You must be signed in to change notification settings - Fork 0
/
interp_Lproxy.py
99 lines (94 loc) · 3.47 KB
/
interp_Lproxy.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
from ast import *
from interp_Lfun import Function
from interp_Llambda import InterpLlambda, ClosureTuple
from interp_Ldyn import Tagged
from interp_Lcast import InterpLcast
from utils import *
class InterpLproxy(InterpLcast):
def apply_fun(self, fun, args, e):
match fun:
case ClosureTuple(elts, arity):
return self.apply_fun(elts[0], [elts] + args, e)
case _:
return super().apply_fun(fun, args, e)
def type_to_tag(self, typ):
match typ:
case ProxyOrTupleType(elt_types):
return 'tuple'
case ProxyOrListType(elt_type):
return 'tuple' # ?
case ListType(elt_type): # move to different file?
return 'tuple'
case _:
return super().type_to_tag(typ)
def interp_exp(self, e, env):
match e:
case RawTuple(es):
return [self.interp_exp(e, env) for e in es]
case TupleProxy(tup, reads, source, target):
reads_ = self.interp_exp(reads, env)
return ProxiedTuple(self.interp_exp(tup, env), reads_)
case ListProxy(lst, read, write, source, target):
read_ = self.interp_exp(read, env)
write_ = self.interp_exp(write, env)
return ProxiedList(self.interp_exp(lst, env), read_, write_)
case InjectTupleProxy(proxy, typ):
p = self.interp_exp(proxy, env)
return ProxiedTuple(p[0], p[1])
case InjectTuple(tup):
return self.interp_exp(tup, env)
case InjectListProxy(proxy, typ):
p = self.interp_exp(proxy, env)
return ProxiedList(p[0], p[1], p[2])
case InjectList(tup):
return self.interp_exp(tup, env)
case Call(Name('is_tuple_proxy'), [arg]):
p = self.interp_exp(arg, env)
match p:
case ProxiedTuple(tup, reads):
return True
case _:
return False
case Call(Name('is_array_proxy'), [arg]):
p = self.interp_exp(arg, env)
match p:
case ProxiedList(lst, read, write):
return True
case _:
return False
case Call(Name('proxy_tuple_load'), [tup, index]):
p = self.interp_exp(tup, env)
i = self.interp_exp(index, env)
return self.interp_getitem(p, i)
case Call(Name('proxy_tuple_len'), [tup]):
t = self.interp_exp(tup, env)
return self.interp_len(t)
case Call(Name('proxy_array_len'), [tup]):
t = self.interp_exp(tup, env)
return self.interp_len(t)
case Call(Name('proxy_array_load'), [arr, index]):
a = self.interp_exp(arr, env)
i = self.interp_exp(index, env)
return self.interp_getitem(a, i)
case Call(Name('proxy_array_store'), [arr, index, value]):
a = self.interp_exp(arr, env)
i = self.interp_exp(index, env)
v = self.interp_exp(value, env)
self.interp_setitem(a, i, v)
return None
case Call(Name('project_array'), [array]):
return self.interp_exp(array, env)
case Call(Name('project_tuple'), [tup]):
return self.interp_exp(tup, env)
case _:
return super().interp_exp(e, env)
def interp_stmt(self, s, env, cont):
match s:
case Assign([Call(Name('any_load'), [tup, index])], value):
t = self.interp_exp(tup, env)
i = self.interp_exp(index, env)
v = self.interp_exp(value, env)
self.interp_setitem(t, i, v)
return self.interp_stmts(cont, env)
case _:
return super().interp_stmt(s, env, cont)