-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathInterpreter.oz
156 lines (146 loc) · 4.92 KB
/
Interpreter.oz
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
* Author: Shubham Singh
* Interpreter.oz
*/
functor
import
Browser(browse: Browse)
define
\insert 'Stack.oz'
\insert 'SingleAssignmentStore.oz'
\insert 'ProcessRecords.oz'
\insert 'ProcessProc.oz'
\insert 'Unify.oz'
\insert 'Test.oz'
TopValue = {NewCell nil}
fun {DeclareVar X Env}
DeclareRecord in
fun {DeclareRecord Pairs Env}
case Pairs of
H|T then {DeclareRecord T {DeclareVar H Env}}
else Env
end
end
case X of
ident(Y) then {Adjoin Env env(Y:{AddKeyToSAS})}
[] [record L Pairs] then
{DeclareRecord {Map Pairs fun {$ X} X.2.1 end} Env}
else raise error('Declartion of variable') end
end
end
proc {Interpreter AST}
{Browse stackTop#store}
{AddStack sepair(stmt:AST env:nil)}
local InterpreterAux Scheduler in
proc {InterpreterAux}
TopValue := {Pop}
{Browse @TopValue#{Dictionary.entries Store}}
if @TopValue == nil then {Browse 'Thread Completed'} {Scheduler}
else
case @TopValue.stmt of
nil then {InterpreterAux}
% skip
[] [nop] then
{ResetSuspendCounter}
{InterpreterAux}
% local X in S end
[] [var X S] then
{Push stk(stmt: S env: {DeclareVar X @TopValue.env})}
{ResetSuspendCounter}
{InterpreterAux}
% X=Y
[] [bind X Y] then
{Unify X Y @TopValue.env @TopValue.env}
{ResetSuspendCounter}
{InterpreterAux}
% if P then S1 else S2 end
[] [conditional ident(P) S1 S2] then Predicate = {RetrieveFromSAS @TopValue.env.P} in
case Predicate
of literal(true) then
{ResetSuspendCounter}
{Push stk(stmt:S1 env:@TopValue.env)}
[] literal(false) then
{ResetSuspendCounter}
{Push stk(stmt:S2 env:@TopValue.env)}
[] equivalence(X) then
{Push @TopValue}
{SuspendCurrentThread}
else raise error('unknown error') end
end
{InterpreterAux}
% case x of p then s1 else s2 end
[] [match ident(X) P S1 S2] then Predicate = {RetrieveFromSAS @TopValue.env.X} CurrentIndex = @Index in
case Predicate
of equivalence(X) then
{Push @TopValue}
{SuspendCurrentThread}
else
{ResetSuspendCounter}
try MatchEnv in % if unification fails, do S2
MatchEnv = {DeclareVar P @TopValue.env}
{Unify ident(X) P MatchEnv MatchEnv} % P==X ? S1 : S2
{Push stk(stmt:S1 env:MatchEnv)}
catch incompatibleTypes(_ _) then
{RemoveKeysfromSAS @Index-CurrentIndex}
{Push stk(stmt:S2 env:@TopValue.env)}
end
end
{InterpreterAux}
% 'function application'
[] apply|ident(F)|Params then Function FuncEnv FuncStmt FuncParams in
Function = {RetrieveFromSAS @TopValue.env.F}
case Function
of equivalence(X) then
{Push @TopValue}
{SuspendCurrentThread}
[] procedure|X then
{ResetSuspendCounter}
FuncParams = Function.2.1
if {Length FuncParams} == {Length Params}then skip
else raise error('Cannot Apply F on Params') end
end
FuncEnv = Function.2.2.2.1
FuncStmt = Function.2.2.1
{Push stk(stmt:FuncStmt env:{GetProcEnv FuncEnv Params FuncParams @TopValue.env})}
else raise error('unknown error') end
end
{InterpreterAux}
[] [sum X Y Z] then
{Unify Z X#'+'#Y @TopValue.env @TopValue.env}
{ResetSuspendCounter}
{InterpreterAux}
[] [subtract X Y Z] then
{Unify Z X#'-'#Y @TopValue.env @TopValue.env}
{ResetSuspendCounter}
{InterpreterAux}
[] [divide X Y Z] then
{Unify Z X#'/'#Y @TopValue.env @TopValue.env}
{ResetSuspendCounter}
{InterpreterAux}
[] [product X Y Z] then
{Unify Z X#'*'#Y @TopValue.env @TopValue.env}
{ResetSuspendCounter}
{InterpreterAux}
[] [thrd S] then
{AddStack sepair(stmt:S env:@TopValue.env)}
{ResetSuspendCounter}
{InterpreterAux}
[] X|Xs then
{ResetSuspendCounter}
if Xs \=nil then
{Push stk(stmt:Xs env:@TopValue.env)}
end
{Push stk(stmt: X env: @TopValue.env)}
{InterpreterAux}
else raise error('Unhandled Statement') end
end
end
end
proc {Scheduler}
if @MultiSemanticStack == nil then {Browse 'Interpretation Completed'} else {InterpreterAux} end
end
{Scheduler}
end
end
{TestCases}
end