Skip to content

Commit fcec6b7

Browse files
committed
basic: separate evaluation of the function and its arguments (DEBUG step4)
This is a prerequisite for merging macroexpand into EVAL.
1 parent 9206563 commit fcec6b7

File tree

3 files changed

+77
-27
lines changed

3 files changed

+77
-27
lines changed

impls/basic/step2_eval.in.bas

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -102,31 +102,46 @@ SUB EVAL
102102
GOSUB EMPTY_Q
103103
IF R THEN R=A:GOSUB INC_REF_R:GOTO EVAL_RETURN
104104

105+
A0=Z%(A+2)
106+
105107
EVAL_INVOKE:
106-
CALL EVAL_AST
107-
W=R
108108

109-
REM if error, return f/args for release by caller
109+
REM evaluate A0
110+
GOSUB PUSH_A
111+
A=A0:CALL EVAL
112+
GOSUB POP_A
110113
IF ER<>-2 THEN GOTO EVAL_RETURN
111114

112-
AR=Z%(R+1): REM rest
113-
F=Z%(R+2)
115+
REM set F, push it in the stack for release after call
116+
GOSUB PUSH_R
117+
F=R
114118

115119
GOSUB TYPE_F
116120
T=T-8
117121
IF 0<T THEN ON T GOTO EVAL_DO_FUNCTION
118122

119-
REM if error, pop and return f/args for release by caller
120-
R=-1:ER=-1:E$="apply of non-function":GOTO EVAL_INVOKE_DONE
123+
REM if error, pop and return f for release by caller
124+
GOSUB POP_R
125+
ER=-1:E$="apply of non-function":GOTO EVAL_RETURN
121126

122127
EVAL_DO_FUNCTION:
123128
REM regular function
124129

130+
REM Evaluate the arguments
131+
A=Z%(A+1):CALL EVAL_AST
132+
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN
133+
134+
REM set F and AR, push AR (after F) in the stack for release after call
135+
GOSUB PEEK_Q:F=Q
136+
GOSUB PUSH_R
137+
AR=R
138+
125139
GOSUB DO_FUNCTION
126140

127-
EVAL_INVOKE_DONE:
128141
REM pop and release f/args
129-
AY=W:GOSUB RELEASE
142+
GOSUB POP_Q:AY=Q:GOSUB RELEASE
143+
GOSUB POP_Q:AY=Q
144+
GOSUB RELEASE
130145

131146
EVAL_RETURN:
132147
REM AZ=R: B=1: GOSUB PR_STR

impls/basic/step3_env.in.bas

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -172,30 +172,43 @@ SUB EVAL
172172
A=A2:CALL EVAL: REM eval A2 using let_env
173173
GOTO EVAL_RETURN
174174
EVAL_INVOKE:
175-
CALL EVAL_AST
176-
W=R
177175

178-
REM if error, return f/args for release by caller
176+
REM evaluate A0
177+
GOSUB PUSH_A
178+
A=A0:CALL EVAL
179+
GOSUB POP_A
179180
IF ER<>-2 THEN GOTO EVAL_RETURN
180181

181-
AR=Z%(R+1): REM rest
182-
F=Z%(R+2)
182+
REM set F, push it in the stack for release after call
183+
GOSUB PUSH_R
184+
F=R
183185

184186
GOSUB TYPE_F
185187
T=T-8
186188
IF 0<T THEN ON T GOTO EVAL_DO_FUNCTION
187189

188-
REM if error, pop and return f/args for release by caller
189-
R=-1:ER=-1:E$="apply of non-function":GOTO EVAL_INVOKE_DONE
190+
REM if error, pop and return f for release by caller
191+
GOSUB POP_R
192+
ER=-1:E$="apply of non-function":GOTO EVAL_RETURN
190193

191194
EVAL_DO_FUNCTION:
192195
REM regular function
193196

197+
REM Evaluate the arguments
198+
A=Z%(A+1):CALL EVAL_AST
199+
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN
200+
201+
REM set F and AR, push AR (after F) in the stack for release after call
202+
GOSUB PEEK_Q:F=Q
203+
GOSUB PUSH_R
204+
AR=R
205+
194206
GOSUB DO_FUNCTION
195207

196-
EVAL_INVOKE_DONE:
197208
REM pop and release f/args
198-
AY=W:GOSUB RELEASE
209+
GOSUB POP_Q:AY=Q:GOSUB RELEASE
210+
GOSUB POP_Q:AY=Q
211+
GOSUB RELEASE
199212

200213
EVAL_RETURN:
201214
REM AZ=R: B=1: GOSUB PR_STR

impls/basic/step4_if_fn_do.in.bas

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -213,38 +213,60 @@ SUB EVAL
213213
GOTO EVAL_RETURN
214214

215215
EVAL_INVOKE:
216-
CALL EVAL_AST
217216

218-
REM if error, return f/args for release by caller
217+
REM evaluate A0
218+
GOSUB PUSH_A
219+
A=A0:CALL EVAL
220+
GOSUB POP_A
219221
IF ER<>-2 THEN GOTO EVAL_RETURN
220222

221-
REM push f/args for release after call
223+
REM set F, push it in the stack for release after call
222224
GOSUB PUSH_R
223-
224-
AR=Z%(R+1): REM rest
225-
F=Z%(R+2)
225+
F=R
226226

227227
GOSUB TYPE_F
228228
T=T-8
229229
IF 0<T THEN ON T GOTO EVAL_DO_FUNCTION,EVAL_DO_MAL_FUNCTION
230230

231-
REM if error, pop and return f/args for release by caller
231+
REM if error, pop and return f for release by caller
232232
GOSUB POP_R
233233
ER=-1:E$="apply of non-function":GOTO EVAL_RETURN
234234

235+
REM Duplicate evaluation of args in order to prepare step8.
236+
235237
EVAL_DO_FUNCTION:
236238
REM regular function
239+
240+
REM Evaluate the arguments
241+
A=Z%(A+1):CALL EVAL_AST
242+
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN
243+
244+
REM set F and AR, push AR (after F) in the stack for release after call
245+
GOSUB PEEK_Q:F=Q
246+
GOSUB PUSH_R
247+
AR=R
248+
237249
IF Z%(F+1)<65 THEN GOSUB DO_FUNCTION:GOTO EVAL_DO_FUNCTION_SKIP
238250
REM for recur functions (apply, map, swap!), use GOTO
239251
IF Z%(F+1)>64 THEN CALL DO_TCO_FUNCTION
240252
EVAL_DO_FUNCTION_SKIP:
241253

242254
REM pop and release f/args
255+
GOSUB POP_Q:AY=Q:GOSUB RELEASE
243256
GOSUB POP_Q:AY=Q
244257
GOSUB RELEASE
245258
GOTO EVAL_RETURN
246259

247260
EVAL_DO_MAL_FUNCTION:
261+
262+
REM Evaluate the arguments
263+
A=Z%(A+1):CALL EVAL_AST
264+
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN
265+
266+
REM set F and AR, push AR (after F) in the stack for release after call
267+
GOSUB PEEK_Q:F=Q
268+
GOSUB PUSH_R
269+
AR=R
248270
Q=E:GOSUB PUSH_Q: REM save the current environment for release
249271

250272
REM create new environ using env and params stored in function
@@ -263,9 +285,9 @@ SUB EVAL
263285
REM actually returns (LV+1)
264286
LV=LV+1:GOSUB PEND_A_LV:LV=LV-1
265287

266-
REM pop and release f/args
288+
REM pop f/args, release f
267289
GOSUB POP_Q:AY=Q
268-
GOSUB RELEASE
290+
GOSUB POP_Q:AY=Q:GOSUB RELEASE
269291

270292
REM A set above
271293
E=R:GOTO EVAL_TCO_RECUR: REM TCO loop

0 commit comments

Comments
 (0)