mirror of
https://github.com/kanaka/mal.git
synced 2024-09-21 02:27:10 +03:00
4202ef7bf1
- Use variables A1, A2, B2 for Z%(A+1), Z%(A+2), Z%(B+2) respectively. - Replace Z%(R)=Z%(R)+32 with GOSUB INC_REF_R - Add functions TYPE_A and TYPE_F for (Z%(A)AND 31) and (Z%(F)AND 31) respectively. - Inline NATIVE_FUNCTION and MAL_FUNCTION. All together saves over 500 bytes so increase Z% value memory by 250 entries.
90 lines
1.9 KiB
QBasic
90 lines
1.9 KiB
QBasic
|
|
REM ENV_NEW(C) -> R
|
|
ENV_NEW:
|
|
REM allocate the data hashmap
|
|
GOSUB HASHMAP
|
|
AY=R
|
|
|
|
REM set the outer and data pointer
|
|
T=13:L=R:M=C:GOSUB ALLOC
|
|
GOSUB RELEASE: REM environment takes ownership
|
|
RETURN
|
|
|
|
REM see RELEASE types.in.bas for environment cleanup
|
|
|
|
REM ENV_NEW_BINDS(C, A, B) -> R
|
|
ENV_NEW_BINDS:
|
|
GOSUB ENV_NEW
|
|
E=R
|
|
REM process bindings
|
|
ENV_NEW_BINDS_LOOP:
|
|
IF Z%(A+1)=0 THEN R=E:RETURN
|
|
REM get/deref the key from A
|
|
K=Z%(A+2)
|
|
|
|
IF S$(Z%(K+1))="&" THEN GOTO EVAL_NEW_BINDS_VARGS
|
|
|
|
EVAL_NEW_BINDS_1x1:
|
|
REM get/deref the key from B
|
|
C=Z%(B+2)
|
|
REM set the binding in the environment data
|
|
GOSUB ENV_SET
|
|
REM go to next element of A and B
|
|
A=Z%(A+1)
|
|
B=Z%(B+1)
|
|
GOTO ENV_NEW_BINDS_LOOP
|
|
|
|
EVAL_NEW_BINDS_VARGS:
|
|
REM get/deref the key from next element of A
|
|
A=Z%(A+1)
|
|
K=Z%(A+2)
|
|
REM the value is the remaining list in B
|
|
A=B:T=6:GOSUB FORCE_SEQ_TYPE
|
|
C=R
|
|
REM set the binding in the environment data
|
|
GOSUB ENV_SET
|
|
R=E
|
|
AY=C:GOSUB RELEASE: REM list is owned by environment
|
|
RETURN
|
|
|
|
REM ENV_SET(E, K, C) -> R
|
|
ENV_SET:
|
|
H=Z%(E+1)
|
|
GOSUB ASSOC1
|
|
Z%(E+1)=R
|
|
R=C
|
|
RETURN
|
|
|
|
REM ENV_SET_S(E, B$, C) -> R
|
|
ENV_SET_S:
|
|
H=Z%(E+1)
|
|
GOSUB ASSOC1_S
|
|
Z%(E+1)=R
|
|
R=C
|
|
RETURN
|
|
|
|
REM ENV_FIND(E, K) -> R
|
|
REM Returns environment (R) containing K. If found, value found is
|
|
REM in R4
|
|
SUB ENV_FIND
|
|
T=E
|
|
ENV_FIND_LOOP:
|
|
H=Z%(T+1)
|
|
REM More efficient to use GET for value (R) and contains? (R3)
|
|
GOSUB HASHMAP_GET
|
|
REM if we found it, save value in R4 for ENV_GET
|
|
IF R3=1 THEN R4=R:R=T:GOTO ENV_FIND_DONE
|
|
T=Z%(T+2): REM get outer environment
|
|
IF T>0 THEN GOTO ENV_FIND_LOOP
|
|
R=-1
|
|
ENV_FIND_DONE:
|
|
END SUB
|
|
|
|
REM ENV_GET(E, K) -> R
|
|
ENV_GET:
|
|
CALL ENV_FIND
|
|
IF R=-1 THEN ER=-1:E$="'"+S$(Z%(K+1))+"' not found":GOTO ENV_GET_RETURN
|
|
R=R4
|
|
GOSUB INC_REF_R
|
|
GOTO ENV_GET_RETURN
|