Skip to content

Commit 823185d

Browse files
committed
basic: separate evaluation of the function and its arguments
This commit is a prerequisite for merging macroexpand into EVAL. It may introduce a memory leak, see #707 and the lines with (?) in steps4-A.
1 parent 9206563 commit 823185d

File tree

9 files changed

+271
-88
lines changed

9 files changed

+271
-88
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: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -213,38 +213,61 @@ 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
270+
248271
Q=E:GOSUB PUSH_Q: REM save the current environment for release
249272

250273
REM create new environ using env and params stored in function
@@ -263,9 +286,9 @@ SUB EVAL
263286
REM actually returns (LV+1)
264287
LV=LV+1:GOSUB PEND_A_LV:LV=LV-1
265288

266-
REM pop and release f/args
267-
GOSUB POP_Q:AY=Q
268-
GOSUB RELEASE
289+
REM pop f/args, do not release (?)
290+
GOSUB POP_Q
291+
GOSUB POP_Q
269292

270293
REM A set above
271294
E=R:GOTO EVAL_TCO_RECUR: REM TCO loop

impls/basic/step5_tco.in.bas

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -237,38 +237,61 @@ SUB EVAL
237237
GOTO EVAL_RETURN
238238

239239
EVAL_INVOKE:
240-
CALL EVAL_AST
241240

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

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

251251
GOSUB TYPE_F
252252
T=T-8
253253
IF 0<T THEN ON T GOTO EVAL_DO_FUNCTION,EVAL_DO_MAL_FUNCTION
254254

255-
REM if error, pop and return f/args for release by caller
255+
REM if error, pop and return f for release by caller
256256
GOSUB POP_R
257257
ER=-1:E$="apply of non-function":GOTO EVAL_RETURN
258258

259+
REM Duplicate evaluation of args in order to prepare step8.
260+
259261
EVAL_DO_FUNCTION:
260262
REM regular function
263+
264+
REM Evaluate the arguments
265+
A=Z%(A+1):CALL EVAL_AST
266+
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN
267+
268+
REM set F and AR, push AR (after F) in the stack for release after call
269+
GOSUB PEEK_Q:F=Q
270+
GOSUB PUSH_R
271+
AR=R
272+
261273
IF Z%(F+1)<65 THEN GOSUB DO_FUNCTION:GOTO EVAL_DO_FUNCTION_SKIP
262274
REM for recur functions (apply, map, swap!), use GOTO
263275
IF Z%(F+1)>64 THEN CALL DO_TCO_FUNCTION
264276
EVAL_DO_FUNCTION_SKIP:
265277

266278
REM pop and release f/args
279+
GOSUB POP_Q:AY=Q:GOSUB RELEASE
267280
GOSUB POP_Q:AY=Q
268281
GOSUB RELEASE
269282
GOTO EVAL_RETURN
270283

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

274297
REM create new environ using env and params stored in function
@@ -287,9 +310,9 @@ SUB EVAL
287310
REM actually returns (LV+1)
288311
LV=LV+1:GOSUB PEND_A_LV:LV=LV-1
289312

290-
REM pop and release f/args
291-
GOSUB POP_Q:AY=Q
292-
GOSUB RELEASE
313+
REM pop f/args, do not release (?)
314+
GOSUB POP_Q
315+
GOSUB POP_Q
293316

294317
REM A set above
295318
E=R:GOTO EVAL_TCO_RECUR: REM TCO loop

impls/basic/step6_file.in.bas

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -237,38 +237,61 @@ SUB EVAL
237237
GOTO EVAL_RETURN
238238

239239
EVAL_INVOKE:
240-
CALL EVAL_AST
241240

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

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

251251
GOSUB TYPE_F
252252
T=T-8
253253
IF 0<T THEN ON T GOTO EVAL_DO_FUNCTION,EVAL_DO_MAL_FUNCTION
254254

255-
REM if error, pop and return f/args for release by caller
255+
REM if error, pop and return f for release by caller
256256
GOSUB POP_R
257257
ER=-1:E$="apply of non-function":GOTO EVAL_RETURN
258258

259+
REM Duplicate evaluation of args in order to prepare step8.
260+
259261
EVAL_DO_FUNCTION:
260262
REM regular function
263+
264+
REM Evaluate the arguments
265+
A=Z%(A+1):CALL EVAL_AST
266+
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN
267+
268+
REM set F and AR, push AR (after F) in the stack for release after call
269+
GOSUB PEEK_Q:F=Q
270+
GOSUB PUSH_R
271+
AR=R
272+
261273
IF Z%(F+1)<65 THEN GOSUB DO_FUNCTION:GOTO EVAL_DO_FUNCTION_SKIP
262274
REM for recur functions (apply, map, swap!), use GOTO
263275
IF Z%(F+1)>64 THEN CALL DO_TCO_FUNCTION
264276
EVAL_DO_FUNCTION_SKIP:
265277

266278
REM pop and release f/args
279+
GOSUB POP_Q:AY=Q:GOSUB RELEASE
267280
GOSUB POP_Q:AY=Q
268281
GOSUB RELEASE
269282
GOTO EVAL_RETURN
270283

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

274297
REM create new environ using env and params stored in function
@@ -287,9 +310,9 @@ SUB EVAL
287310
REM actually returns (LV+1)
288311
LV=LV+1:GOSUB PEND_A_LV:LV=LV-1
289312

290-
REM pop and release f/args
291-
GOSUB POP_Q:AY=Q
292-
GOSUB RELEASE
313+
REM pop f/args, do not release (?)
314+
GOSUB POP_Q
315+
GOSUB POP_Q
293316

294317
REM A set above
295318
E=R:GOTO EVAL_TCO_RECUR: REM TCO loop

0 commit comments

Comments
 (0)