Commit | Line | Data |
---|---|---|
b7b1787f JM |
1 | GOTO MAIN |
2 | ||
3 | REM $INCLUDE: 'readline.in.bas' | |
4 | REM $INCLUDE: 'types.in.bas' | |
5 | REM $INCLUDE: 'reader.in.bas' | |
6 | REM $INCLUDE: 'printer.in.bas' | |
7 | ||
8 | REM READ(A$) -> R% | |
9 | MAL_READ: | |
10 | GOSUB READ_STR | |
11 | RETURN | |
12 | ||
13 | REM EVAL_AST(A%, E%) -> R% | |
14 | EVAL_AST: | |
15 | ZL%=ZL%+2: ZZ%(ZL%-1)=E%: ZZ%(ZL%)=A% | |
16 | IF ER%=1 THEN GOTO EVAL_AST_RETURN | |
17 | ||
18 | REM AZ%=A%: GOSUB PR_STR | |
19 | REM PRINT "EVAL_AST: " + R$ + "(" + STR$(R%) + ")" | |
20 | ||
21 | T%=Z%(A%,0) | |
22 | IF T%=5 THEN EVAL_AST_SYMBOL | |
0cb556e0 JM |
23 | IF T%=6 THEN EVAL_AST_SEQ |
24 | IF T%=8 THEN EVAL_AST_SEQ | |
25 | IF T%=10 THEN EVAL_AST_SEQ | |
b7b1787f JM |
26 | R%=A% |
27 | GOTO EVAL_AST_RETURN | |
28 | ||
29 | EVAL_AST_SYMBOL: | |
30 | HM%=E%: K%=A%: GOSUB HASHMAP_GET | |
31 | IF T3%=0 THEN ER%=1: ER$="'" + ZS$(Z%(A%,1)) + "' not found" | |
32 | GOTO EVAL_AST_RETURN | |
33 | ||
0cb556e0 JM |
34 | EVAL_AST_SEQ: |
35 | REM push type of sequence | |
36 | ZL%=ZL%+1 | |
37 | ZZ%(ZL%)=T% | |
38 | REM push sequence index | |
39 | ZL%=ZL%+1 | |
40 | ZZ%(ZL%)=-1 | |
41 | REM push future return value (new sequence) | |
b7b1787f JM |
42 | ZL%=ZL%+1 |
43 | ZZ%(ZL%)=ZI% | |
0cb556e0 | 44 | REM push previous new sequence entry |
b7b1787f JM |
45 | ZL%=ZL%+1 |
46 | ZZ%(ZL%)=ZI% | |
47 | ||
0cb556e0 JM |
48 | EVAL_AST_SEQ_LOOP: |
49 | REM create new sequence entry | |
50 | Z%(ZI%,0)=ZZ%(ZL%-3) | |
b7b1787f JM |
51 | Z%(ZI%,1)=0 |
52 | ZI%=ZI%+1 | |
53 | ||
0cb556e0 JM |
54 | REM update index |
55 | ZZ%(ZL%-2)=ZZ%(ZL%-2)+1 | |
56 | ||
57 | REM check if we are done evaluating the sequence | |
58 | IF Z%(A%,1)=0 THEN GOTO EVAL_AST_SEQ_LOOP_DONE | |
b7b1787f JM |
59 | |
60 | REM create value ptr placeholder | |
61 | Z%(ZI%,0)=15 | |
62 | Z%(ZI%,1)=0 | |
63 | ZI%=ZI%+1 | |
64 | ||
0cb556e0 JM |
65 | REM if hashmap, skip eval of even entries (keys) |
66 | R%=A%+1 | |
67 | IF (ZZ%(ZL%-3)=10) AND ((ZZ%(ZL%-2) AND 1)=0) THEN GOTO EVAL_AST_SEQ_SKIP | |
68 | ||
b7b1787f JM |
69 | REM call EVAL for each entry |
70 | A%=A%+1: GOSUB EVAL | |
71 | A%=A%-1 | |
72 | ||
0cb556e0 JM |
73 | EVAL_AST_SEQ_SKIP: |
74 | ||
75 | REM update previous sequence entry to point to current entry | |
b7b1787f JM |
76 | Z%(ZZ%(ZL%),1)=ZI% |
77 | REM update previous value pointer to evaluated entry | |
78 | Z%(ZZ%(ZL%)+1,1)=R% | |
79 | REM update previous ptr to current entry | |
80 | ZZ%(ZL%)=ZI% | |
81 | ||
0cb556e0 | 82 | REM process the next sequence entry |
b7b1787f JM |
83 | A%=Z%(A%,1) |
84 | ||
0cb556e0 JM |
85 | GOTO EVAL_AST_SEQ_LOOP |
86 | EVAL_AST_SEQ_LOOP_DONE: | |
87 | REM pop previous new sequence entry value | |
b7b1787f | 88 | ZL%=ZL%-1 |
0cb556e0 | 89 | REM pop return value (new seq), index, and seq type |
b7b1787f | 90 | R%=ZZ%(ZL%) |
0cb556e0 | 91 | ZL%=ZL%-3 |
b7b1787f JM |
92 | GOTO EVAL_AST_RETURN |
93 | ||
94 | EVAL_AST_RETURN: | |
95 | E%=ZZ%(ZL%-1): A%=ZZ%(ZL%): ZL%=ZL%-2 | |
96 | RETURN | |
97 | ||
98 | REM EVAL(A%, E%)) -> R% | |
99 | EVAL: | |
100 | ZL%=ZL%+2: ZZ%(ZL%-1)=E%: ZZ%(ZL%)=A% | |
101 | IF ER%=1 THEN GOTO EVAL_RETURN | |
102 | ||
103 | REM AZ%=A%: GOSUB PR_STR | |
104 | REM PRINT "EVAL: " + R$ + "(" + STR$(R%) + ")" | |
105 | ||
106 | GOSUB LIST_Q | |
107 | IF R% THEN GOTO APPLY_LIST | |
108 | REM ELSE | |
109 | GOSUB EVAL_AST | |
110 | GOTO EVAL_RETURN | |
111 | ||
112 | APPLY_LIST: | |
113 | GOSUB EMPTY_Q | |
114 | IF R% THEN R%=A%: GOTO EVAL_RETURN | |
115 | ||
0cb556e0 JM |
116 | EVAL_INVOKE: |
117 | GOSUB EVAL_AST | |
118 | IF ER%=1 THEN GOTO EVAL_RETURN | |
119 | F%=R%+1 | |
120 | AR%=Z%(R%,1): REM REST | |
121 | R%=F%: GOSUB DEREF | |
122 | F%=R% | |
123 | IF Z%(F%,0)<>12 THEN ER%=1: ER$="apply of non-function": GOTO EVAL_RETURN | |
124 | GOSUB DO_FUNCTION | |
125 | GOTO EVAL_RETURN | |
b7b1787f JM |
126 | |
127 | EVAL_RETURN: | |
128 | E%=ZZ%(ZL%-1): A%=ZZ%(ZL%): ZL%=ZL%-2 | |
129 | RETURN | |
130 | ||
131 | REM DO_FUNCTION(F%, AR%) | |
132 | DO_FUNCTION: | |
133 | AZ%=F%: GOSUB PR_STR | |
134 | F$=R$ | |
135 | AZ%=AR%: GOSUB PR_STR | |
136 | AR$=R$ | |
137 | ||
138 | REM Get the function number | |
139 | FF%=Z%(F%,1) | |
140 | ||
141 | REM Get argument values | |
142 | R%=AR%+1: GOSUB DEREF | |
143 | AA%=Z%(R%,1) | |
144 | R%=Z%(AR%,1)+1: GOSUB DEREF | |
145 | AB%=Z%(R%,1) | |
146 | ||
147 | REM Allocate the return value | |
148 | R%=ZI% | |
149 | ZI%=ZI%+1 | |
150 | ||
151 | REM Switch on the function number | |
152 | IF FF%=1 THEN DO_ADD | |
153 | IF FF%=2 THEN DO_SUB | |
154 | IF FF%=3 THEN DO_MULT | |
155 | IF FF%=4 THEN DO_DIV | |
156 | ER%=1: ER$="unknown function" + STR$(FF%): RETURN | |
157 | ||
158 | DO_ADD: | |
159 | Z%(R%,0)=2 | |
160 | Z%(R%,1)=AA%+AB% | |
161 | GOTO DO_FUNCTION_DONE | |
162 | DO_SUB: | |
163 | Z%(R%,0)=2 | |
164 | Z%(R%,1)=AA%-AB% | |
165 | GOTO DO_FUNCTION_DONE | |
166 | DO_MULT: | |
167 | Z%(R%,0)=2 | |
168 | Z%(R%,1)=AA%*AB% | |
169 | GOTO DO_FUNCTION_DONE | |
170 | DO_DIV: | |
171 | Z%(R%,0)=2 | |
172 | Z%(R%,1)=AA%/AB% | |
173 | GOTO DO_FUNCTION_DONE | |
174 | ||
175 | DO_FUNCTION_DONE: | |
176 | RETURN | |
177 | ||
178 | REM PRINT(A%) -> R$ | |
179 | MAL_PRINT: | |
180 | AZ%=A%: GOSUB PR_STR | |
181 | RETURN | |
182 | ||
183 | REM REP(A$) -> R$ | |
184 | REM Assume RE% has repl_env | |
185 | REP: | |
186 | GOSUB MAL_READ | |
187 | IF ER% THEN RETURN | |
188 | A%=R%: E%=RE%: GOSUB EVAL | |
189 | IF ER% THEN RETURN | |
190 | A%=R%: GOSUB MAL_PRINT | |
191 | IF ER% THEN RETURN | |
192 | RETURN | |
193 | ||
194 | REM MAIN program | |
195 | MAIN: | |
196 | GOSUB INIT_MEMORY | |
197 | ||
198 | REM repl_env | |
199 | GOSUB HASHMAP | |
200 | RE%=R% | |
201 | ||
202 | REM + function | |
203 | A%=1: GOSUB NATIVE_FUNCTION | |
204 | HM%=RE%: K$="+": V%=R%: GOSUB ASSOC1_S | |
205 | RE%=R% | |
206 | ||
207 | REM - function | |
208 | A%=2: GOSUB NATIVE_FUNCTION | |
209 | HM%=RE%: K$="-": V%=R%: GOSUB ASSOC1_S | |
210 | RE%=R% | |
211 | ||
212 | REM * function | |
213 | A%=3: GOSUB NATIVE_FUNCTION | |
214 | HM%=RE%: K$="*": V%=R%: GOSUB ASSOC1_S | |
215 | RE%=R% | |
216 | ||
217 | REM / function | |
218 | A%=4: GOSUB NATIVE_FUNCTION | |
219 | HM%=RE%: K$="/": V%=R%: GOSUB ASSOC1_S | |
220 | RE%=R% | |
221 | ||
222 | AZ%=RE%: GOSUB PR_STR | |
223 | PRINT "env: " + R$ + "(" + STR$(RE%) + ")" | |
224 | ||
225 | MAIN_LOOP: | |
226 | A$="user> " | |
227 | GOSUB READLINE: REM /* call input parser */ | |
228 | IF EOF=1 THEN GOTO MAIN_DONE | |
229 | A$=R$: GOSUB REP: REM /* call REP */ | |
230 | IF ER% THEN GOTO ERROR | |
231 | PRINT R$ | |
232 | GOTO MAIN_LOOP | |
233 | ||
234 | ERROR: | |
235 | PRINT "Error: " + ER$ | |
236 | ER%=0 | |
237 | ER$="" | |
238 | GOTO MAIN_LOOP | |
239 | ||
240 | MAIN_DONE: | |
0cb556e0 | 241 | PRINT "Free: " + STR$(FRE(0)) |
b7b1787f JM |
242 | END |
243 |