Skip to content

Commit 2d71f99

Browse files
committed
basic: separate evaluation of the function and its arguments
This is a prerequisite for merging macroexpand into EVAL.
1 parent 8833932 commit 2d71f99

10 files changed

+300
-78
lines changed

impls/basic/step2_eval.in.bas

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,25 +102,50 @@ SUB EVAL
102102
GOTO EVAL_RETURN
103103

104104
APPLY_LIST:
105+
105106
GOSUB EMPTY_Q
106107
IF R THEN R=A:GOSUB INC_REF_R:GOTO EVAL_RETURN
107108

108109
EVAL_INVOKE:
109-
CALL EVAL_AST
110-
W=R
111110

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

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

118121
GOSUB TYPE_F
119-
IF T<>9 THEN R=-1:ER=-1:E$="apply of non-function":GOTO EVAL_INVOKE_DONE
120-
GOSUB DO_FUNCTION
121-
EVAL_INVOKE_DONE:
122-
AY=W:GOSUB RELEASE
123-
GOTO EVAL_RETURN
122+
123+
REM ON .. GOTO here reduces the diff with later steps.
124+
T=T-8
125+
IF 0<T THEN ON T GOTO EVAL_DO_FUNCTION
126+
127+
REM if error, pop and return f for release by caller
128+
GOSUB POP_R
129+
ER=-1:E$="apply of non-function":GOTO EVAL_RETURN
130+
131+
EVAL_DO_FUNCTION:
132+
REM regular function
133+
134+
REM Evaluate the arguments
135+
A=Z%(A+1):CALL EVAL_AST
136+
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN
137+
138+
REM set F and AR, push AR (after F) in the stack for release after call
139+
GOSUB PEEK_Q:F=Q
140+
GOSUB PUSH_R
141+
AR=R
142+
143+
GOSUB DO_FUNCTION
144+
145+
REM pop and release f/args
146+
GOSUB POP_Q:AY=Q:GOSUB RELEASE
147+
GOSUB POP_Q:AY=Q
148+
GOSUB RELEASE
124149

125150
EVAL_RETURN:
126151
REM AZ=R: B=1: GOSUB PR_STR

impls/basic/step3_env.in.bas

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ SUB EVAL
106106
GOTO EVAL_RETURN
107107

108108
APPLY_LIST:
109+
109110
GOSUB EMPTY_Q
110111
IF R THEN R=A:GOSUB INC_REF_R:GOTO EVAL_RETURN
111112

@@ -172,21 +173,45 @@ SUB EVAL
172173
A=A2:CALL EVAL: REM eval A2 using let_env
173174
GOTO EVAL_RETURN
174175
EVAL_INVOKE:
175-
CALL EVAL_AST
176-
W=R
177176

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

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

184187
GOSUB TYPE_F
185-
IF T<>9 THEN R=-1:ER=-1:E$="apply of non-function":GOTO EVAL_INVOKE_DONE
186-
GOSUB DO_FUNCTION
187-
EVAL_INVOKE_DONE:
188-
AY=W:GOSUB RELEASE
189-
GOTO EVAL_RETURN
188+
189+
REM ON .. GOTO here reduces the diff with later steps.
190+
T=T-8
191+
IF 0<T THEN ON T GOTO EVAL_DO_FUNCTION
192+
193+
REM if error, pop and return f for release by caller
194+
GOSUB POP_R
195+
ER=-1:E$="apply of non-function":GOTO EVAL_RETURN
196+
197+
EVAL_DO_FUNCTION:
198+
REM regular function
199+
200+
REM Evaluate the arguments
201+
A=Z%(A+1):CALL EVAL_AST
202+
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN
203+
204+
REM set F and AR, push AR (after F) in the stack for release after call
205+
GOSUB PEEK_Q:F=Q
206+
GOSUB PUSH_R
207+
AR=R
208+
209+
GOSUB DO_FUNCTION
210+
211+
REM pop and release f/args
212+
GOSUB POP_Q:AY=Q:GOSUB RELEASE
213+
GOSUB POP_Q:AY=Q
214+
GOSUB RELEASE
190215

191216
EVAL_RETURN:
192217
REM AZ=R: B=1: GOSUB PR_STR

impls/basic/step4_if_fn_do.in.bas

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ SUB EVAL
109109
GOTO EVAL_RETURN
110110

111111
APPLY_LIST:
112+
112113
GOSUB EMPTY_Q
113114
IF R THEN R=A:GOSUB INC_REF_R:GOTO EVAL_RETURN
114115

@@ -213,40 +214,64 @@ SUB EVAL
213214
GOTO EVAL_RETURN
214215

215216
EVAL_INVOKE:
216-
CALL EVAL_AST
217217

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

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

227228
REM if metadata, get the actual object
228229
GOSUB TYPE_F
229230
IF T=14 THEN F=Z%(F+1):GOSUB TYPE_F
230231

231-
ON T-8 GOTO EVAL_DO_FUNCTION,EVAL_DO_MAL_FUNCTION,EVAL_DO_MAL_FUNCTION
232+
T=T-8
233+
IF 0<T THEN ON T GOTO EVAL_DO_FUNCTION,EVAL_DO_MAL_FUNCTION
232234

233-
REM if error, pop and return f/args for release by caller
235+
REM if error, pop and return f for release by caller
234236
GOSUB POP_R
235237
ER=-1:E$="apply of non-function":GOTO EVAL_RETURN
236238

239+
REM Duplicate evaluation of args in order to prepare step8.
240+
237241
EVAL_DO_FUNCTION:
238242
REM regular function
243+
244+
REM Evaluate the arguments
245+
A=Z%(A+1):CALL EVAL_AST
246+
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN
247+
248+
REM set F and AR, push AR (after F) in the stack for release after call
249+
GOSUB PEEK_Q:F=Q
250+
GOSUB PUSH_R
251+
AR=R
252+
239253
IF Z%(F+1)<65 THEN GOSUB DO_FUNCTION:GOTO EVAL_DO_FUNCTION_SKIP
240254
REM for recur functions (apply, map, swap!), use GOTO
241255
IF Z%(F+1)>64 THEN CALL DO_TCO_FUNCTION
242256
EVAL_DO_FUNCTION_SKIP:
243257

244258
REM pop and release f/args
259+
GOSUB POP_Q:AY=Q:GOSUB RELEASE
245260
GOSUB POP_Q:AY=Q
246261
GOSUB RELEASE
247262
GOTO EVAL_RETURN
248263

249264
EVAL_DO_MAL_FUNCTION:
265+
266+
REM Evaluate the arguments
267+
A=Z%(A+1):CALL EVAL_AST
268+
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN
269+
270+
REM set F and AR, push AR (after F) in the stack for release after call
271+
GOSUB PEEK_Q:F=Q
272+
GOSUB PUSH_R
273+
AR=R
274+
250275
Q=E:GOSUB PUSH_Q: REM save the current environment for release
251276

252277
REM create new environ using env and params stored in function
@@ -266,6 +291,7 @@ SUB EVAL
266291
LV=LV+1:GOSUB PEND_A_LV:LV=LV-1
267292

268293
REM pop and release f/args
294+
GOSUB POP_Q:AY=Q:GOSUB RELEASE
269295
GOSUB POP_Q:AY=Q
270296
GOSUB RELEASE
271297

impls/basic/step5_tco.in.bas

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ SUB EVAL
115115
GOTO EVAL_RETURN
116116

117117
APPLY_LIST:
118+
118119
GOSUB EMPTY_Q
119120
IF R THEN R=A:GOSUB INC_REF_R:GOTO EVAL_RETURN
120121

@@ -237,40 +238,64 @@ SUB EVAL
237238
GOTO EVAL_RETURN
238239

239240
EVAL_INVOKE:
240-
CALL EVAL_AST
241241

242-
REM if error, return f/args for release by caller
242+
REM evaluate A0
243+
GOSUB PUSH_A
244+
A=A0:CALL EVAL
245+
GOSUB POP_A
243246
IF ER<>-2 THEN GOTO EVAL_RETURN
244247

245-
REM push f/args for release after call
248+
REM set F, push it in the stack for release after call
246249
GOSUB PUSH_R
247-
248-
AR=Z%(R+1): REM rest
249-
F=Z%(R+2)
250+
F=R
250251

251252
REM if metadata, get the actual object
252253
GOSUB TYPE_F
253254
IF T=14 THEN F=Z%(F+1):GOSUB TYPE_F
254255

255-
ON T-8 GOTO EVAL_DO_FUNCTION,EVAL_DO_MAL_FUNCTION,EVAL_DO_MAL_FUNCTION
256+
T=T-8
257+
IF 0<T THEN ON T GOTO EVAL_DO_FUNCTION,EVAL_DO_MAL_FUNCTION
256258

257-
REM if error, pop and return f/args for release by caller
259+
REM if error, pop and return f for release by caller
258260
GOSUB POP_R
259261
ER=-1:E$="apply of non-function":GOTO EVAL_RETURN
260262

263+
REM Duplicate evaluation of args in order to prepare step8.
264+
261265
EVAL_DO_FUNCTION:
262266
REM regular function
267+
268+
REM Evaluate the arguments
269+
A=Z%(A+1):CALL EVAL_AST
270+
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN
271+
272+
REM set F and AR, push AR (after F) in the stack for release after call
273+
GOSUB PEEK_Q:F=Q
274+
GOSUB PUSH_R
275+
AR=R
276+
263277
IF Z%(F+1)<65 THEN GOSUB DO_FUNCTION:GOTO EVAL_DO_FUNCTION_SKIP
264278
REM for recur functions (apply, map, swap!), use GOTO
265279
IF Z%(F+1)>64 THEN CALL DO_TCO_FUNCTION
266280
EVAL_DO_FUNCTION_SKIP:
267281

268282
REM pop and release f/args
283+
GOSUB POP_Q:AY=Q:GOSUB RELEASE
269284
GOSUB POP_Q:AY=Q
270285
GOSUB RELEASE
271286
GOTO EVAL_RETURN
272287

273288
EVAL_DO_MAL_FUNCTION:
289+
290+
REM Evaluate the arguments
291+
A=Z%(A+1):CALL EVAL_AST
292+
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN
293+
294+
REM set F and AR, push AR (after F) in the stack for release after call
295+
GOSUB PEEK_Q:F=Q
296+
GOSUB PUSH_R
297+
AR=R
298+
274299
Q=E:GOSUB PUSH_Q: REM save the current environment for release
275300

276301
REM create new environ using env and params stored in function
@@ -290,6 +315,7 @@ SUB EVAL
290315
LV=LV+1:GOSUB PEND_A_LV:LV=LV-1
291316

292317
REM pop and release f/args
318+
GOSUB POP_Q:AY=Q:GOSUB RELEASE
293319
GOSUB POP_Q:AY=Q
294320
GOSUB RELEASE
295321

impls/basic/step6_file.in.bas

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ SUB EVAL
115115
GOTO EVAL_RETURN
116116

117117
APPLY_LIST:
118+
118119
GOSUB EMPTY_Q
119120
IF R THEN R=A:GOSUB INC_REF_R:GOTO EVAL_RETURN
120121

@@ -237,40 +238,64 @@ SUB EVAL
237238
GOTO EVAL_RETURN
238239

239240
EVAL_INVOKE:
240-
CALL EVAL_AST
241241

242-
REM if error, return f/args for release by caller
242+
REM evaluate A0
243+
GOSUB PUSH_A
244+
A=A0:CALL EVAL
245+
GOSUB POP_A
243246
IF ER<>-2 THEN GOTO EVAL_RETURN
244247

245-
REM push f/args for release after call
248+
REM set F, push it in the stack for release after call
246249
GOSUB PUSH_R
247-
248-
AR=Z%(R+1): REM rest
249-
F=Z%(R+2)
250+
F=R
250251

251252
REM if metadata, get the actual object
252253
GOSUB TYPE_F
253254
IF T=14 THEN F=Z%(F+1):GOSUB TYPE_F
254255

255-
ON T-8 GOTO EVAL_DO_FUNCTION,EVAL_DO_MAL_FUNCTION,EVAL_DO_MAL_FUNCTION
256+
T=T-8
257+
IF 0<T THEN ON T GOTO EVAL_DO_FUNCTION,EVAL_DO_MAL_FUNCTION
256258

257-
REM if error, pop and return f/args for release by caller
259+
REM if error, pop and return f for release by caller
258260
GOSUB POP_R
259261
ER=-1:E$="apply of non-function":GOTO EVAL_RETURN
260262

263+
REM Duplicate evaluation of args in order to prepare step8.
264+
261265
EVAL_DO_FUNCTION:
262266
REM regular function
267+
268+
REM Evaluate the arguments
269+
A=Z%(A+1):CALL EVAL_AST
270+
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN
271+
272+
REM set F and AR, push AR (after F) in the stack for release after call
273+
GOSUB PEEK_Q:F=Q
274+
GOSUB PUSH_R
275+
AR=R
276+
263277
IF Z%(F+1)<65 THEN GOSUB DO_FUNCTION:GOTO EVAL_DO_FUNCTION_SKIP
264278
REM for recur functions (apply, map, swap!), use GOTO
265279
IF Z%(F+1)>64 THEN CALL DO_TCO_FUNCTION
266280
EVAL_DO_FUNCTION_SKIP:
267281

268282
REM pop and release f/args
283+
GOSUB POP_Q:AY=Q:GOSUB RELEASE
269284
GOSUB POP_Q:AY=Q
270285
GOSUB RELEASE
271286
GOTO EVAL_RETURN
272287

273288
EVAL_DO_MAL_FUNCTION:
289+
290+
REM Evaluate the arguments
291+
A=Z%(A+1):CALL EVAL_AST
292+
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN
293+
294+
REM set F and AR, push AR (after F) in the stack for release after call
295+
GOSUB PEEK_Q:F=Q
296+
GOSUB PUSH_R
297+
AR=R
298+
274299
Q=E:GOSUB PUSH_Q: REM save the current environment for release
275300

276301
REM create new environ using env and params stored in function
@@ -290,6 +315,7 @@ SUB EVAL
290315
LV=LV+1:GOSUB PEND_A_LV:LV=LV-1
291316

292317
REM pop and release f/args
318+
GOSUB POP_Q:AY=Q:GOSUB RELEASE
293319
GOSUB POP_Q:AY=Q
294320
GOSUB RELEASE
295321

0 commit comments

Comments
 (0)