3 REM $INCLUDE: 'types.in.bas'
4 REM $INCLUDE: 'readline.in.bas'
5 REM $INCLUDE: 'reader.in.bas'
6 REM $INCLUDE: 'printer.in.bas'
8 REM $INCLUDE: 'debug.in.bas'
15 REM EVAL_AST(A, E) -> R
19 REM push A and E on the stack
23 IF ER
<>-2 THEN GOTO EVAL_AST_RETURN
28 IF T
=5 THEN GOTO EVAL_AST_SYMBOL
29 IF T
>=6 AND T
<=8 THEN GOTO EVAL_AST_SEQ
31 REM scalar: deref to actual value and inc ref cnt
37 H
=E
:K
=A
:GOSUB HASHMAP_GET
39 IF R3
=0 THEN ER
=-1:E
$="'"+S$(Z%(A,1))+"' not found
":GOTO EVAL_AST_RETURN
44 REM allocate the first entry (T already set above)
47 REM push type of sequence
49 REM push sequence index
51 REM push future return value (new sequence)
53 REM push previous new sequence entry
57 REM check if we are done evaluating the source sequence
58 IF Z%(A,1)=0 THEN GOTO EVAL_AST_SEQ_LOOP_DONE
60 REM if hashmap, skip eval of even entries (keys)
61 Q=3:GOSUB PEEK_Q_Q:T=Q
62 REM get and update index
65 IF T=8 AND ((Q-1)AND 1)=0 THEN GOTO EVAL_AST_DO_REF
69 R=A+1:GOSUB DEREF_R: REM deref to target of referred entry
70 Z%(R,0)=Z%(R,0)+32: REM inc ref cnt of referred value
71 GOTO EVAL_AST_ADD_VALUE
74 REM call EVAL for each entry
77 GOSUB DEREF_R: REM deref to target of evaluated entry
81 REM update previous value pointer to evaluated entry
85 IF ER<>-2 THEN GOTO EVAL_AST_SEQ_LOOP_DONE
87 REM allocate the next entry
88 REM same new sequence entry type
89 Q=3:GOSUB PEEK_Q_Q:T=Q
92 REM update previous sequence entry value to point to new entry
95 REM update previous ptr to current entry
98 REM process the next sequence entry from source list
101 GOTO EVAL_AST_SEQ_LOOP
102 EVAL_AST_SEQ_LOOP_DONE:
103 REM get return value (new seq), index, and seq type
106 REM pop previous, return, index and type
107 GOSUB POP_Q:GOSUB POP_Q:GOSUB POP_Q:GOSUB POP_Q
111 REM pop A and E off the stack
120 LV=LV+1: REM track basic return stack level
122 REM push A and E on the stack
126 IF ER<>-2 THEN GOTO EVAL_RETURN
128 REM AZ=A:B=1:GOSUB PR_STR
129 REM PRINT "EVAL
: "+R$+" [A:"+STR
$(A)+", LV
:"+STR$(LV)+"]"
134 IF R THEN GOTO APPLY_LIST
141 IF R THEN R=A:Z%(R,0)=Z%(R,0)+32:GOTO EVAL_RETURN
147 REM if error, return f/args for release by caller
148 IF ER<>-2 THEN GOTO EVAL_RETURN
152 R=F:GOSUB DEREF_R:F=R
153 IF (Z%(F,0)AND 31)<>9 THEN ER=-1:E$="apply of non-function":GOTO EVAL_RETURN
160 LV
=LV
-1: REM track basic return stack level
166 REM pop A and E off the stack
172 REM DO_FUNCTION(F, AR)
179 REM Get the function number
182 REM Get argument values
183 R
=AR
+1:GOSUB DEREF_R
:A
=Z
%(R
,1)
184 R
=Z
%(AR
,1)+1:GOSUB DEREF_R
:B
=Z
%(R
,1)
186 REM Switch on the function number
187 IF G
=1 THEN GOTO DO_ADD
188 IF G
=2 THEN GOTO DO_SUB
189 IF G
=3 THEN GOTO DO_MULT
190 IF G
=4 THEN GOTO DO_DIV
191 ER
=-1:E
$="unknown function"+STR$(G):RETURN
194 T=2:L=A+B:GOSUB ALLOC
195 GOTO DO_FUNCTION_DONE
197 T=2:L=A-B:GOSUB ALLOC
198 GOTO DO_FUNCTION_DONE
200 T=2:L=A*B:GOSUB ALLOC
201 GOTO DO_FUNCTION_DONE
203 T=2:L=A/B:GOSUB ALLOC
204 GOTO DO_FUNCTION_DONE
211 AZ=A:B=1:GOSUB PR_STR
215 REM Assume D has repl_env
220 IF ER<>-2 THEN GOTO REP_DONE
224 IF ER<>-2 THEN GOTO REP_DONE
230 REM Release memory from MAL_READ and EVAL
231 IF R2<>0 THEN AY=R2:GOSUB RELEASE
232 IF R1<>0 THEN AY=R1:GOSUB RELEASE
246 A=1:GOSUB NATIVE_FUNCTION
247 H=D:B$="+":C=R:GOSUB ASSOC1_S:D=R
250 A=2:GOSUB NATIVE_FUNCTION
251 H=D:B$="-":C=R:GOSUB ASSOC1_S:D=R
254 A=3:GOSUB NATIVE_FUNCTION
255 H=D:B$="*":C=R:GOSUB ASSOC1_S:D=R
258 A=4:GOSUB NATIVE_FUNCTION
259 H=D:B$="/":C=R:GOSUB ASSOC1_S:D=R
261 ZT=ZI: REM top of memory after base repl_env
264 A$="user> ":GOSUB READLINE
: REM call input parser
265 IF EZ
=1 THEN GOTO QUIT
267 A
$=R$:CALL REP
: REM call REP
269 IF ER
<>-2 THEN GOSUB PRINT_ERROR
:GOTO REPL_LOOP
274 REM GOSUB PR_MEMORY_SUMMARY