DO_APPLY:
F=AA
AR=Z%(AR,1)
- A=AR:GOSUB COUNT:R4=R
+ B=AR:GOSUB COUNT:R4=R
A=Z%(AR+1,1)
REM no intermediate args, but not a list, so convert it first
AR=R:CALL APPLY
- REM pop apply args are release them
+ REM pop apply args and release them
AY=X%(X):X=X-1:GOSUB RELEASE
REM set the result value
Z%(X%(X-2)+1,1)=R
+ IF ER<>-2 THEN GOTO DO_MAP_DONE
+
REM restore F
F=X%(X-1)
GOTO DO_MAP_LOOP
DO_MAP_DONE:
- REM get return val
- R=X%(X-3)
+ REM if no error, get return val
+ IF ER=-2 THEN R=X%(X-3)
+ REM otherwise, free the return value and return nil
+ IF ER<>-2 THEN R=0:AY=X%(X-3):GOSUB RELEASE
+
REM pop everything off stack
X=X-4
GOTO DO_TCO_FUNCTION_DONE
REM Switch on the function number
IF FF>59 THEN ER=-1:ER$="unknown function"+STR$(FF):RETURN
- ON FF/10+1 GOTO DO_1_9,DO_10_19,DO_20_29,DO_30_39,DO_40_49,DO_50_56
+ ON FF/10+1 GOTO DO_1_9,DO_10_19,DO_20_29,DO_30_39,DO_40_49,DO_50_59
DO_1_9:
ON FF GOTO DO_EQUAL_Q,DO_THROW,DO_NIL_Q,DO_TRUE_Q,DO_FALSE_Q,DO_STRING_Q,DO_SYMBOL,DO_SYMBOL_Q,DO_KEYWORD
ON FF-29 GOTO DO_VECTOR_Q,DO_HASH_MAP,DO_MAP_Q,DO_ASSOC,DO_THROW,DO_GET,DO_CONTAINS,DO_KEYS,DO_VALS,DO_SEQUENTIAL_Q
DO_40_49:
ON FF-39 GOTO DO_CONS,DO_CONCAT,DO_NTH,DO_FIRST,DO_REST,DO_EMPTY_Q,DO_COUNT,DO_THROW,DO_THROW,DO_WITH_META
- DO_50_56:
+ DO_50_59:
ON FF-49 GOTO DO_META,DO_ATOM,DO_ATOM_Q,DO_DEREF,DO_RESET_BANG,DO_EVAL,DO_READ_FILE
+ REM ,DO_PR_MEMORY_SUMMARY
DO_EQUAL_Q:
A=AA:B=AB:GOSUB EQUAL_Q
AB=R
GOTO DO_CONCAT_LOOP
DO_NTH:
+ B=AA:GOSUB COUNT
B=Z%(AB,1)
- A=AA:GOSUB COUNT
IF R<=B THEN R=0:ER=-1:ER$="nth: index out of range":RETURN
DO_NTH_LOOP:
IF B=0 THEN GOTO DO_NTH_DONE
IF Z%(AA,1)=0 THEN R=2
RETURN
DO_COUNT:
- A=AA:GOSUB COUNT
+ B=AA:GOSUB COUNT
T=2:L=R:GOSUB ALLOC
RETURN
K$="eval":A=55:GOSUB INIT_CORE_SET_FUNCTION
K$="read-file":A=56:GOSUB INIT_CORE_SET_FUNCTION
+ REM K$="pr-memory-summary":A=57:GOSUB INIT_CORE_SET_FUNCTION
REM these are in DO_TCO_FUNCTION
K$="apply":A=61:GOSUB INIT_CORE_SET_FUNCTION
IF T7<9 THEN L=T7
T8=R: REM save previous value for release
T=X%(X-1):N=R:GOSUB ALLOC
- AY=T8:GOSUB RELEASE: REM list takes ownership
+ REM list takes ownership
+ IF L<9 THEN AY=L:GOSUB RELEASE
+ AY=T8:GOSUB RELEASE
REM if previous element is the first element then set
REM the first to the new element
IF Z%(A,1)=0 THEN GOTO EVAL_AST_SEQ_LOOP_DONE
REM if hashmap, skip eval of even entries (keys)
- IF (X%(X-3)=8) AND ((X%(X-2) AND 1)=0) THEN GOTO EVAL_AST_DO_REF
+ IF (X%(X-3)=8) AND ((X%(X-2)AND1)=0) THEN GOTO EVAL_AST_DO_REF
GOTO EVAL_AST_DO_EVAL
EVAL_AST_DO_REF:
REM push A and E on the stack
X=X+2:X%(X-1)=E:X%(X)=A
+ IF ER<>-2 THEN GOTO EVAL_RETURN
+
REM AZ=A:PR=1:GOSUB PR_STR
REM PRINT "EVAL: "+R$+" [A:"+STR$(A)+", LV:"+STR$(LV)+"]"
IF Z%(A,1)=0 THEN GOTO EVAL_AST_SEQ_LOOP_DONE
REM if hashmap, skip eval of even entries (keys)
- IF (X%(X-3)=8) AND ((X%(X-2) AND 1)=0) THEN GOTO EVAL_AST_DO_REF
+ IF (X%(X-3)=8) AND ((X%(X-2)AND1)=0) THEN GOTO EVAL_AST_DO_REF
GOTO EVAL_AST_DO_EVAL
EVAL_AST_DO_REF:
REM push A and E on the stack
X=X+2:X%(X-1)=E:X%(X)=A
+ IF ER<>-2 THEN GOTO EVAL_RETURN
+
REM AZ=A:PR=1:GOSUB PR_STR
REM PRINT "EVAL: "+R$+" [A:"+STR$(A)+", LV:"+STR$(LV)+"]"
A=Z%(A1,1)+1:CALL EVAL
A1=X%(X):X=X-1: REM pop A1
+ IF ER<>-2 THEN GOTO EVAL_LET_LOOP_DONE
+
REM set environment: even A1 key to odd A1 eval'd above
K=A1+1:V=R:GOSUB ENV_SET
AY=R:GOSUB RELEASE: REM release our use, ENV_SET took ownership
IF Z%(A,1)=0 THEN GOTO EVAL_AST_SEQ_LOOP_DONE
REM if hashmap, skip eval of even entries (keys)
- IF (X%(X-3)=8) AND ((X%(X-2) AND 1)=0) THEN GOTO EVAL_AST_DO_REF
+ IF (X%(X-3)=8) AND ((X%(X-2)AND1)=0) THEN GOTO EVAL_AST_DO_REF
GOTO EVAL_AST_DO_EVAL
EVAL_AST_DO_REF:
EVAL_TCO_RECUR:
+ IF ER<>-2 THEN GOTO EVAL_RETURN
+
REM AZ=A:PR=1:GOSUB PR_STR
REM PRINT "EVAL: "+R$+" [A:"+STR$(A)+", LV:"+STR$(LV)+"]"
A=Z%(A1,1)+1:CALL EVAL
A1=X%(X):X=X-1: REM pop A1
+ IF ER<>-2 THEN GOTO EVAL_LET_LOOP_DONE
+
REM set environment: even A1 key to odd A1 eval'd above
K=A1+1:V=R:GOSUB ENV_SET
AY=R:GOSUB RELEASE: REM release our use, ENV_SET took ownership
EVAL_IF_FALSE:
AY=R:GOSUB RELEASE
REM if no false case (A3), return nil
- IF Z%(Z%(Z%(A,1),1),1)=0 THEN R=0:GOTO EVAL_RETURN
+ B=A:GOSUB COUNT
+ IF R<4 THEN R=0:GOTO EVAL_RETURN
GOSUB EVAL_GET_A3: REM set A1 - A3 after EVAL
A=A3:GOTO EVAL_TCO_RECUR: REM TCO loop
IF X%(X-6)=2 AND Z%(Z%(A,1),1)=0 THEN GOTO EVAL_AST_SEQ_LOOP_DONE
REM if hashmap, skip eval of even entries (keys)
- IF (X%(X-3)=8) AND ((X%(X-2) AND 1)=0) THEN GOTO EVAL_AST_DO_REF
+ IF (X%(X-3)=8) AND ((X%(X-2)AND1)=0) THEN GOTO EVAL_AST_DO_REF
GOTO EVAL_AST_DO_EVAL
EVAL_AST_DO_REF:
EVAL_TCO_RECUR:
+ IF ER<>-2 THEN GOTO EVAL_RETURN
+
REM AZ=A:PR=1:GOSUB PR_STR
REM PRINT "EVAL: "+R$+" [A:"+STR$(A)+", LV:"+STR$(LV)+"]"
A=Z%(A1,1)+1:CALL EVAL
A1=X%(X):X=X-1: REM pop A1
+ IF ER<>-2 THEN GOTO EVAL_LET_LOOP_DONE
+
REM set environment: even A1 key to odd A1 eval'd above
K=A1+1:V=R:GOSUB ENV_SET
AY=R:GOSUB RELEASE: REM release our use, ENV_SET took ownership
EVAL_IF_FALSE:
AY=R:GOSUB RELEASE
REM if no false case (A3), return nil
- IF Z%(Z%(Z%(A,1),1),1)=0 THEN R=0:GOTO EVAL_RETURN
+ B=A:GOSUB COUNT
+ IF R<4 THEN R=0:GOTO EVAL_RETURN
GOSUB EVAL_GET_A3: REM set A1 - A3 after EVAL
A=A3:GOTO EVAL_TCO_RECUR: REM TCO loop
IF X%(X-6)=2 AND Z%(Z%(A,1),1)=0 THEN GOTO EVAL_AST_SEQ_LOOP_DONE
REM if hashmap, skip eval of even entries (keys)
- IF (X%(X-3)=8) AND ((X%(X-2) AND 1)=0) THEN GOTO EVAL_AST_DO_REF
+ IF (X%(X-3)=8) AND ((X%(X-2)AND1)=0) THEN GOTO EVAL_AST_DO_REF
GOTO EVAL_AST_DO_EVAL
EVAL_AST_DO_REF:
EVAL_TCO_RECUR:
+ IF ER<>-2 THEN GOTO EVAL_RETURN
+
REM AZ=A:PR=1:GOSUB PR_STR
REM PRINT "EVAL: "+R$+" [A:"+STR$(A)+", LV:"+STR$(LV)+"]"
A=Z%(A1,1)+1:CALL EVAL
A1=X%(X):X=X-1: REM pop A1
+ IF ER<>-2 THEN GOTO EVAL_LET_LOOP_DONE
+
REM set environment: even A1 key to odd A1 eval'd above
K=A1+1:V=R:GOSUB ENV_SET
AY=R:GOSUB RELEASE: REM release our use, ENV_SET took ownership
EVAL_IF_FALSE:
AY=R:GOSUB RELEASE
REM if no false case (A3), return nil
- IF Z%(Z%(Z%(A,1),1),1)=0 THEN R=0:GOTO EVAL_RETURN
+ B=A:GOSUB COUNT
+ IF R<4 THEN R=0:GOTO EVAL_RETURN
GOSUB EVAL_GET_A3: REM set A1 - A3 after EVAL
A=A3:GOTO EVAL_TCO_RECUR: REM TCO loop
IF X%(X-6)=2 AND Z%(Z%(A,1),1)=0 THEN GOTO EVAL_AST_SEQ_LOOP_DONE
REM if hashmap, skip eval of even entries (keys)
- IF (X%(X-3)=8) AND ((X%(X-2) AND 1)=0) THEN GOTO EVAL_AST_DO_REF
+ IF (X%(X-3)=8) AND ((X%(X-2)AND1)=0) THEN GOTO EVAL_AST_DO_REF
GOTO EVAL_AST_DO_EVAL
EVAL_AST_DO_REF:
EVAL_TCO_RECUR:
+ IF ER<>-2 THEN GOTO EVAL_RETURN
+
REM AZ=A:PR=1:GOSUB PR_STR
REM PRINT "EVAL: "+R$+" [A:"+STR$(A)+", LV:"+STR$(LV)+"]"
A=Z%(A1,1)+1:CALL EVAL
A1=X%(X):X=X-1: REM pop A1
+ IF ER<>-2 THEN GOTO EVAL_LET_LOOP_DONE
+
REM set environment: even A1 key to odd A1 eval'd above
K=A1+1:V=R:GOSUB ENV_SET
AY=R:GOSUB RELEASE: REM release our use, ENV_SET took ownership
EVAL_IF_FALSE:
AY=R:GOSUB RELEASE
REM if no false case (A3), return nil
- IF Z%(Z%(Z%(A,1),1),1)=0 THEN R=0:GOTO EVAL_RETURN
+ B=A:GOSUB COUNT
+ IF R<4 THEN R=0:GOTO EVAL_RETURN
GOSUB EVAL_GET_A3: REM set A1 - A3 after EVAL
A=A3:GOTO EVAL_TCO_RECUR: REM TCO loop
IF X%(X-6)=2 AND Z%(Z%(A,1),1)=0 THEN GOTO EVAL_AST_SEQ_LOOP_DONE
REM if hashmap, skip eval of even entries (keys)
- IF (X%(X-3)=8) AND ((X%(X-2) AND 1)=0) THEN GOTO EVAL_AST_DO_REF
+ IF (X%(X-3)=8) AND ((X%(X-2)AND1)=0) THEN GOTO EVAL_AST_DO_REF
GOTO EVAL_AST_DO_EVAL
EVAL_AST_DO_REF:
EVAL_TCO_RECUR:
+ IF ER<>-2 THEN GOTO EVAL_RETURN
+
REM AZ=A:PR=1:GOSUB PR_STR
REM PRINT "EVAL: "+R$+" [A:"+STR$(A)+", LV:"+STR$(LV)+"]"
A=Z%(A1,1)+1:CALL EVAL
A1=X%(X):X=X-1: REM pop A1
+ IF ER<>-2 THEN GOTO EVAL_LET_LOOP_DONE
+
REM set environment: even A1 key to odd A1 eval'd above
K=A1+1:V=R:GOSUB ENV_SET
AY=R:GOSUB RELEASE: REM release our use, ENV_SET took ownership
EVAL_IF_FALSE:
AY=R:GOSUB RELEASE
REM if no false case (A3), return nil
- IF Z%(Z%(Z%(A,1),1),1)=0 THEN R=0:GOTO EVAL_RETURN
+ B=A:GOSUB COUNT
+ IF R<4 THEN R=0:GOTO EVAL_RETURN
GOSUB EVAL_GET_A3: REM set A1 - A3 after EVAL
A=A3:GOTO EVAL_TCO_RECUR: REM TCO loop
EVAL_TCO_RECUR:
+ IF ER<>-2 THEN GOTO EVAL_RETURN
+
REM AZ=A:PR=1:GOSUB PR_STR
REM PRINT "EVAL: "+R$+" [A:"+STR$(A)+", LV:"+STR$(LV)+"]"
A=Z%(A1,1)+1:CALL EVAL
A1=X%(X):X=X-1: REM pop A1
+ IF ER<>-2 THEN GOTO EVAL_LET_LOOP_DONE
+
REM set environment: even A1 key to odd A1 eval'd above
K=A1+1:V=R:GOSUB ENV_SET
AY=R:GOSUB RELEASE: REM release our use, ENV_SET took ownership
REM bind the catch symbol to the error object
K=A1:V=ER:GOSUB ENV_SET
- AY=R:GOSUB RELEASE: REM release out use, env took ownership
+ AY=R:GOSUB RELEASE: REM release our use, env took ownership
REM unset error for catch eval
ER=-2:ER$=""
EVAL_IF_FALSE:
AY=R:GOSUB RELEASE
REM if no false case (A3), return nil
- IF Z%(Z%(Z%(A,1),1),1)=0 THEN R=0:GOTO EVAL_RETURN
+ B=A:GOSUB COUNT
+ IF R<4 THEN R=0:GOTO EVAL_RETURN
GOSUB EVAL_GET_A3: REM set A1 - A3 after EVAL
A=A3:GOTO EVAL_TCO_RECUR: REM TCO loop
EVAL_TCO_RECUR:
+ IF ER<>-2 THEN GOTO EVAL_RETURN
+
REM AZ=A:PR=1:GOSUB PR_STR
REM PRINT "EVAL: "+R$+" [A:"+STR$(A)+", LV:"+STR$(LV)+"]"
A=Z%(A1,1)+1:CALL EVAL
A1=X%(X):X=X-1: REM pop A1
+ IF ER<>-2 THEN GOTO EVAL_LET_LOOP_DONE
+
REM set environment: even A1 key to odd A1 eval'd above
K=A1+1:V=R:GOSUB ENV_SET
AY=R:GOSUB RELEASE: REM release our use, ENV_SET took ownership
REM bind the catch symbol to the error object
K=A1:V=ER:GOSUB ENV_SET
- AY=R:GOSUB RELEASE: REM release out use, env took ownership
+ AY=R:GOSUB RELEASE: REM release our use, env took ownership
REM unset error for catch eval
ER=-2:ER$=""
EVAL_IF_FALSE:
AY=R:GOSUB RELEASE
REM if no false case (A3), return nil
- IF Z%(Z%(Z%(A,1),1),1)=0 THEN R=0:GOTO EVAL_RETURN
+ B=A:GOSUB COUNT
+ IF R<4 THEN R=0:GOTO EVAL_RETURN
GOSUB EVAL_GET_A3: REM set A1 - A3 after EVAL
A=A3:GOTO EVAL_TCO_RECUR: REM TCO loop
IF Z%(A,1)=0 THEN R=1
RETURN
-REM COUNT(A) -> R
+REM COUNT(B) -> R
+REM - returns length of list, not a Z% index
+REM - modifies B
COUNT:
R=-1
DO_COUNT_LOOP:
R=R+1
- IF Z%(A,1)<>0 THEN A=Z%(A,1):GOTO DO_COUNT_LOOP
+ IF Z%(B,1)<>0 THEN B=Z%(B,1):GOTO DO_COUNT_LOOP
RETURN
REM LAST(A) -> R