Skip to content

Commit

Permalink
basic: separate evaluation of the function and its arguments
Browse files Browse the repository at this point in the history
This is a prerequisite for merging macroexpand into EVAL.
  • Loading branch information
asarhaddon committed Nov 16, 2024
1 parent fe075d0 commit 173a352
Show file tree
Hide file tree
Showing 10 changed files with 258 additions and 69 deletions.
33 changes: 24 additions & 9 deletions impls/basic/step2_eval.in.bas
Original file line number Diff line number Diff line change
Expand Up @@ -106,33 +106,48 @@ SUB EVAL
GOSUB EMPTY_Q
IF R THEN R=A:GOSUB INC_REF_R:GOTO EVAL_RETURN

A0=Z%(A+2)

EVAL_INVOKE:
CALL EVAL_AST
W=R

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

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

GOSUB TYPE_F

REM ON .. GOTO here reduces the diff with later steps.
T=T-8
IF 0<T THEN ON T GOTO EVAL_DO_FUNCTION

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

EVAL_DO_FUNCTION:
REM regular function

REM Evaluate the arguments
A=Z%(A+1):CALL EVAL_AST
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN

REM set F and AR, push AR (after F) in the stack for release after call
GOSUB PEEK_Q:F=Q
GOSUB PUSH_R
AR=R

GOSUB DO_FUNCTION

EVAL_INVOKE_DONE:
REM pop and release f/args
AY=W:GOSUB RELEASE
GOSUB POP_Q:AY=Q:GOSUB RELEASE
GOSUB POP_Q:AY=Q
GOSUB RELEASE

EVAL_RETURN:
REM AZ=R: B=1: GOSUB PR_STR
Expand Down
31 changes: 22 additions & 9 deletions impls/basic/step3_env.in.bas
Original file line number Diff line number Diff line change
Expand Up @@ -173,32 +173,45 @@ SUB EVAL
A=A2:CALL EVAL: REM eval A2 using let_env
GOTO EVAL_RETURN
EVAL_INVOKE:
CALL EVAL_AST
W=R

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

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

GOSUB TYPE_F

REM ON .. GOTO here reduces the diff with later steps.
T=T-8
IF 0<T THEN ON T GOTO EVAL_DO_FUNCTION

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

EVAL_DO_FUNCTION:
REM regular function

REM Evaluate the arguments
A=Z%(A+1):CALL EVAL_AST
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN

REM set F and AR, push AR (after F) in the stack for release after call
GOSUB PEEK_Q:F=Q
GOSUB PUSH_R
AR=R

GOSUB DO_FUNCTION

EVAL_INVOKE_DONE:
REM pop and release f/args
AY=W:GOSUB RELEASE
GOSUB POP_Q:AY=Q:GOSUB RELEASE
GOSUB POP_Q:AY=Q
GOSUB RELEASE

EVAL_RETURN:
REM AZ=R: B=1: GOSUB PR_STR
Expand Down
38 changes: 31 additions & 7 deletions impls/basic/step4_if_fn_do.in.bas
Original file line number Diff line number Diff line change
Expand Up @@ -214,16 +214,16 @@ SUB EVAL
GOTO EVAL_RETURN

EVAL_INVOKE:
CALL EVAL_AST

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

REM push f/args for release after call
REM set F, push it in the stack for release after call
GOSUB PUSH_R

AR=Z%(R+1): REM rest
F=Z%(R+2)
F=R

REM if metadata, get the actual object
GOSUB TYPE_F
Expand All @@ -232,23 +232,46 @@ SUB EVAL
T=T-8
IF 0<T THEN ON T GOTO EVAL_DO_FUNCTION,EVAL_DO_MAL_FUNCTION

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

REM Duplicate evaluation of args in order to prepare step8.

EVAL_DO_FUNCTION:
REM regular function

REM Evaluate the arguments
A=Z%(A+1):CALL EVAL_AST
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN

REM set F and AR, push AR (after F) in the stack for release after call
GOSUB PEEK_Q:F=Q
GOSUB PUSH_R
AR=R

IF Z%(F+1)<65 THEN GOSUB DO_FUNCTION:GOTO EVAL_DO_FUNCTION_SKIP
REM for recur functions (apply, map, swap!), use GOTO
IF Z%(F+1)>64 THEN CALL DO_TCO_FUNCTION
EVAL_DO_FUNCTION_SKIP:

REM pop and release f/args
GOSUB POP_Q:AY=Q:GOSUB RELEASE
GOSUB POP_Q:AY=Q
GOSUB RELEASE
GOTO EVAL_RETURN

EVAL_DO_MAL_FUNCTION:

REM Evaluate the arguments
A=Z%(A+1):CALL EVAL_AST
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN

REM set F and AR, push AR (after F) in the stack for release after call
GOSUB PEEK_Q:F=Q
GOSUB PUSH_R
AR=R

Q=E:GOSUB PUSH_Q: REM save the current environment for release

REM create new environ using env and params stored in function
Expand All @@ -268,6 +291,7 @@ SUB EVAL
LV=LV+1:GOSUB PEND_A_LV:LV=LV-1

REM pop and release f/args
GOSUB POP_Q:AY=Q:GOSUB RELEASE
GOSUB POP_Q:AY=Q
GOSUB RELEASE

Expand Down
38 changes: 31 additions & 7 deletions impls/basic/step5_tco.in.bas
Original file line number Diff line number Diff line change
Expand Up @@ -238,16 +238,16 @@ SUB EVAL
GOTO EVAL_RETURN

EVAL_INVOKE:
CALL EVAL_AST

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

REM push f/args for release after call
REM set F, push it in the stack for release after call
GOSUB PUSH_R

AR=Z%(R+1): REM rest
F=Z%(R+2)
F=R

REM if metadata, get the actual object
GOSUB TYPE_F
Expand All @@ -256,23 +256,46 @@ SUB EVAL
T=T-8
IF 0<T THEN ON T GOTO EVAL_DO_FUNCTION,EVAL_DO_MAL_FUNCTION

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

REM Duplicate evaluation of args in order to prepare step8.

EVAL_DO_FUNCTION:
REM regular function

REM Evaluate the arguments
A=Z%(A+1):CALL EVAL_AST
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN

REM set F and AR, push AR (after F) in the stack for release after call
GOSUB PEEK_Q:F=Q
GOSUB PUSH_R
AR=R

IF Z%(F+1)<65 THEN GOSUB DO_FUNCTION:GOTO EVAL_DO_FUNCTION_SKIP
REM for recur functions (apply, map, swap!), use GOTO
IF Z%(F+1)>64 THEN CALL DO_TCO_FUNCTION
EVAL_DO_FUNCTION_SKIP:

REM pop and release f/args
GOSUB POP_Q:AY=Q:GOSUB RELEASE
GOSUB POP_Q:AY=Q
GOSUB RELEASE
GOTO EVAL_RETURN

EVAL_DO_MAL_FUNCTION:

REM Evaluate the arguments
A=Z%(A+1):CALL EVAL_AST
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN

REM set F and AR, push AR (after F) in the stack for release after call
GOSUB PEEK_Q:F=Q
GOSUB PUSH_R
AR=R

Q=E:GOSUB PUSH_Q: REM save the current environment for release

REM create new environ using env and params stored in function
Expand All @@ -292,6 +315,7 @@ SUB EVAL
LV=LV+1:GOSUB PEND_A_LV:LV=LV-1

REM pop and release f/args
GOSUB POP_Q:AY=Q:GOSUB RELEASE
GOSUB POP_Q:AY=Q
GOSUB RELEASE

Expand Down
38 changes: 31 additions & 7 deletions impls/basic/step6_file.in.bas
Original file line number Diff line number Diff line change
Expand Up @@ -238,16 +238,16 @@ SUB EVAL
GOTO EVAL_RETURN

EVAL_INVOKE:
CALL EVAL_AST

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

REM push f/args for release after call
REM set F, push it in the stack for release after call
GOSUB PUSH_R

AR=Z%(R+1): REM rest
F=Z%(R+2)
F=R

REM if metadata, get the actual object
GOSUB TYPE_F
Expand All @@ -256,23 +256,46 @@ SUB EVAL
T=T-8
IF 0<T THEN ON T GOTO EVAL_DO_FUNCTION,EVAL_DO_MAL_FUNCTION

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

REM Duplicate evaluation of args in order to prepare step8.

EVAL_DO_FUNCTION:
REM regular function

REM Evaluate the arguments
A=Z%(A+1):CALL EVAL_AST
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN

REM set F and AR, push AR (after F) in the stack for release after call
GOSUB PEEK_Q:F=Q
GOSUB PUSH_R
AR=R

IF Z%(F+1)<65 THEN GOSUB DO_FUNCTION:GOTO EVAL_DO_FUNCTION_SKIP
REM for recur functions (apply, map, swap!), use GOTO
IF Z%(F+1)>64 THEN CALL DO_TCO_FUNCTION
EVAL_DO_FUNCTION_SKIP:

REM pop and release f/args
GOSUB POP_Q:AY=Q:GOSUB RELEASE
GOSUB POP_Q:AY=Q
GOSUB RELEASE
GOTO EVAL_RETURN

EVAL_DO_MAL_FUNCTION:

REM Evaluate the arguments
A=Z%(A+1):CALL EVAL_AST
IF ER<>-2 THEN GOSUB POP_Q:AY=Q:GOSUB RELEASE:GOTO EVAL_RETURN

REM set F and AR, push AR (after F) in the stack for release after call
GOSUB PEEK_Q:F=Q
GOSUB PUSH_R
AR=R

Q=E:GOSUB PUSH_Q: REM save the current environment for release

REM create new environ using env and params stored in function
Expand All @@ -292,6 +315,7 @@ SUB EVAL
LV=LV+1:GOSUB PEND_A_LV:LV=LV-1

REM pop and release f/args
GOSUB POP_Q:AY=Q:GOSUB RELEASE
GOSUB POP_Q:AY=Q
GOSUB RELEASE

Expand Down
Loading

0 comments on commit 173a352

Please sign in to comment.