2016-09-11 08:11:55 +03:00
|
|
|
|
2016-11-04 08:07:09 +03:00
|
|
|
REM ENV_NEW(C) -> R
|
2016-09-11 08:11:55 +03:00
|
|
|
ENV_NEW:
|
|
|
|
REM allocate the data hashmap
|
|
|
|
GOSUB HASHMAP
|
2016-11-07 02:20:03 +03:00
|
|
|
AY=R
|
2016-09-11 08:11:55 +03:00
|
|
|
|
2016-09-16 07:58:55 +03:00
|
|
|
REM set the outer and data pointer
|
2016-11-18 09:54:04 +03:00
|
|
|
T=13:L=R:M=C:GOSUB ALLOC
|
2016-11-07 02:20:03 +03:00
|
|
|
GOSUB RELEASE: REM environment takes ownership
|
2016-09-11 08:11:55 +03:00
|
|
|
RETURN
|
|
|
|
|
2016-09-16 09:00:58 +03:00
|
|
|
REM see RELEASE types.in.bas for environment cleanup
|
|
|
|
|
2016-11-04 08:07:09 +03:00
|
|
|
REM ENV_NEW_BINDS(C, A, B) -> R
|
2016-09-12 05:36:15 +03:00
|
|
|
ENV_NEW_BINDS:
|
|
|
|
GOSUB ENV_NEW
|
2016-10-15 06:42:56 +03:00
|
|
|
E=R
|
2016-09-12 05:36:15 +03:00
|
|
|
REM process bindings
|
|
|
|
ENV_NEW_BINDS_LOOP:
|
2016-11-18 09:54:04 +03:00
|
|
|
IF Z%(A+1)=0 THEN R=E:RETURN
|
2016-11-04 08:07:09 +03:00
|
|
|
REM get/deref the key from A
|
2016-11-18 09:54:04 +03:00
|
|
|
K=Z%(A+2)
|
2016-09-12 05:36:15 +03:00
|
|
|
|
2016-11-18 09:54:04 +03:00
|
|
|
IF S$(Z%(K+1))="&" THEN GOTO EVAL_NEW_BINDS_VARGS
|
2016-09-12 05:36:15 +03:00
|
|
|
|
|
|
|
EVAL_NEW_BINDS_1x1:
|
2016-11-04 08:07:09 +03:00
|
|
|
REM get/deref the key from B
|
2016-11-18 09:54:04 +03:00
|
|
|
C=Z%(B+2)
|
2016-09-12 05:36:15 +03:00
|
|
|
REM set the binding in the environment data
|
|
|
|
GOSUB ENV_SET
|
2016-11-04 08:07:09 +03:00
|
|
|
REM go to next element of A and B
|
2016-11-18 09:54:04 +03:00
|
|
|
A=Z%(A+1)
|
|
|
|
B=Z%(B+1)
|
2016-09-12 05:36:15 +03:00
|
|
|
GOTO ENV_NEW_BINDS_LOOP
|
|
|
|
|
|
|
|
EVAL_NEW_BINDS_VARGS:
|
2016-11-04 08:07:09 +03:00
|
|
|
REM get/deref the key from next element of A
|
2016-11-18 09:54:04 +03:00
|
|
|
A=Z%(A+1)
|
|
|
|
K=Z%(A+2)
|
2016-11-04 08:07:09 +03:00
|
|
|
REM the value is the remaining list in B
|
|
|
|
A=B:T=6:GOSUB FORCE_SEQ_TYPE
|
|
|
|
C=R
|
2016-09-12 05:36:15 +03:00
|
|
|
REM set the binding in the environment data
|
|
|
|
GOSUB ENV_SET
|
2016-10-15 06:42:56 +03:00
|
|
|
R=E
|
2016-11-04 08:07:09 +03:00
|
|
|
AY=C:GOSUB RELEASE: REM list is owned by environment
|
2016-09-12 05:36:15 +03:00
|
|
|
RETURN
|
|
|
|
|
2016-11-04 08:07:09 +03:00
|
|
|
REM ENV_SET(E, K, C) -> R
|
2016-09-11 08:11:55 +03:00
|
|
|
ENV_SET:
|
2016-11-18 09:54:04 +03:00
|
|
|
H=Z%(E+1)
|
2016-09-11 08:11:55 +03:00
|
|
|
GOSUB ASSOC1
|
2016-11-18 09:54:04 +03:00
|
|
|
Z%(E+1)=R
|
2016-11-04 08:07:09 +03:00
|
|
|
R=C
|
2016-09-11 08:11:55 +03:00
|
|
|
RETURN
|
|
|
|
|
2016-11-10 10:51:02 +03:00
|
|
|
REM ENV_SET_S(E, B$, C) -> R
|
2016-09-11 08:11:55 +03:00
|
|
|
ENV_SET_S:
|
2016-11-18 09:54:04 +03:00
|
|
|
H=Z%(E+1)
|
2016-09-11 08:11:55 +03:00
|
|
|
GOSUB ASSOC1_S
|
2016-11-18 09:54:04 +03:00
|
|
|
Z%(E+1)=R
|
2016-11-04 08:07:09 +03:00
|
|
|
R=C
|
2016-09-11 08:11:55 +03:00
|
|
|
RETURN
|
|
|
|
|
2016-10-15 06:42:56 +03:00
|
|
|
REM ENV_FIND(E, K) -> R
|
|
|
|
REM Returns environment (R) containing K. If found, value found is
|
2016-11-07 02:20:03 +03:00
|
|
|
REM in R4
|
2016-10-26 09:26:05 +03:00
|
|
|
SUB ENV_FIND
|
2016-11-04 08:07:09 +03:00
|
|
|
T=E
|
2016-09-11 08:11:55 +03:00
|
|
|
ENV_FIND_LOOP:
|
2016-11-18 09:54:04 +03:00
|
|
|
H=Z%(T+1)
|
2016-11-07 02:20:03 +03:00
|
|
|
REM More efficient to use GET for value (R) and contains? (R3)
|
2016-09-11 08:11:55 +03:00
|
|
|
GOSUB HASHMAP_GET
|
2016-11-07 02:20:03 +03:00
|
|
|
REM if we found it, save value in R4 for ENV_GET
|
Basic: refactor of hashmaps, map loops, remove derefs.
- Alternate memory layout of hash-maps:
Instead of hash-maps being an alternating sequence of keys and values,
combine the key/values into a single entry. In other words, switch
from this:
8 -> next Z% index (0 for last)
14 key/value (alternating)
To this:
8 -> next Z% index (0 for last)
key value
This requires refactoring of the sequence reader, EVAL_AST and
especially DO_HASHMAP and DO_KEY_VALS. So that leads to the next big
refactoring:
- Change mapping/lapping constructs to share code:
Several pieces of mapping/looping code have a common structure, so
this moves that common structure to types.in.bas: MAP_LOOP_START,
MAP_LOOP_UPDATE, MAP_LOOP_DONE. Then use this code in:
- EVAL_AST
- READ_SEQ_*
- DO_MAP
- DO_HASH_MAP
- DO_KEYS_VALS
This also fixes the issue that several of these looping constructs
were creating new empty sequence entries instead of using the common
ones at the beginning of memory.
- Remove the use of DEREF_*.
This isn't actually needed because we no longer create structure that
refer to multiple levels of type 14 references. Replace DEREF_* with
VAL_* which gets the value of a particular sequence element i.e.
Z%(A+1,1).
All together, the above changes save over 300 bytes.
Also:
- Fix empty nil/false/true entries so they
are treated the same as other types of data with regards to
reference counting and ALLOC/RELEASE.
- Add a new memory summary function in debug.in.bas that just prints
out free, value count, and references for the early scalar and empty
list elements. Comment out the larger one. This saves about 90
bytes.
2016-11-16 07:38:09 +03:00
|
|
|
IF R3=1 THEN R4=R:R=T:GOTO ENV_FIND_DONE
|
2016-11-18 09:54:04 +03:00
|
|
|
T=Z%(T+2): REM get outer environment
|
Basic: refactor of hashmaps, map loops, remove derefs.
- Alternate memory layout of hash-maps:
Instead of hash-maps being an alternating sequence of keys and values,
combine the key/values into a single entry. In other words, switch
from this:
8 -> next Z% index (0 for last)
14 key/value (alternating)
To this:
8 -> next Z% index (0 for last)
key value
This requires refactoring of the sequence reader, EVAL_AST and
especially DO_HASHMAP and DO_KEY_VALS. So that leads to the next big
refactoring:
- Change mapping/lapping constructs to share code:
Several pieces of mapping/looping code have a common structure, so
this moves that common structure to types.in.bas: MAP_LOOP_START,
MAP_LOOP_UPDATE, MAP_LOOP_DONE. Then use this code in:
- EVAL_AST
- READ_SEQ_*
- DO_MAP
- DO_HASH_MAP
- DO_KEYS_VALS
This also fixes the issue that several of these looping constructs
were creating new empty sequence entries instead of using the common
ones at the beginning of memory.
- Remove the use of DEREF_*.
This isn't actually needed because we no longer create structure that
refer to multiple levels of type 14 references. Replace DEREF_* with
VAL_* which gets the value of a particular sequence element i.e.
Z%(A+1,1).
All together, the above changes save over 300 bytes.
Also:
- Fix empty nil/false/true entries so they
are treated the same as other types of data with regards to
reference counting and ALLOC/RELEASE.
- Add a new memory summary function in debug.in.bas that just prints
out free, value count, and references for the early scalar and empty
list elements. Comment out the larger one. This saves about 90
bytes.
2016-11-16 07:38:09 +03:00
|
|
|
IF T>0 THEN GOTO ENV_FIND_LOOP
|
|
|
|
R=-1
|
2016-09-11 08:11:55 +03:00
|
|
|
ENV_FIND_DONE:
|
2016-10-26 09:26:05 +03:00
|
|
|
END SUB
|
2016-09-11 08:11:55 +03:00
|
|
|
|
2016-10-15 06:42:56 +03:00
|
|
|
REM ENV_GET(E, K) -> R
|
2016-09-11 08:11:55 +03:00
|
|
|
ENV_GET:
|
2016-10-26 09:26:05 +03:00
|
|
|
CALL ENV_FIND
|
2016-11-18 09:54:04 +03:00
|
|
|
IF R=-1 THEN ER=-1:E$="'"+S$(Z%(K+1))+"' not found":GOTO ENV_GET_RETURN
|
Basic: refactor of hashmaps, map loops, remove derefs.
- Alternate memory layout of hash-maps:
Instead of hash-maps being an alternating sequence of keys and values,
combine the key/values into a single entry. In other words, switch
from this:
8 -> next Z% index (0 for last)
14 key/value (alternating)
To this:
8 -> next Z% index (0 for last)
key value
This requires refactoring of the sequence reader, EVAL_AST and
especially DO_HASHMAP and DO_KEY_VALS. So that leads to the next big
refactoring:
- Change mapping/lapping constructs to share code:
Several pieces of mapping/looping code have a common structure, so
this moves that common structure to types.in.bas: MAP_LOOP_START,
MAP_LOOP_UPDATE, MAP_LOOP_DONE. Then use this code in:
- EVAL_AST
- READ_SEQ_*
- DO_MAP
- DO_HASH_MAP
- DO_KEYS_VALS
This also fixes the issue that several of these looping constructs
were creating new empty sequence entries instead of using the common
ones at the beginning of memory.
- Remove the use of DEREF_*.
This isn't actually needed because we no longer create structure that
refer to multiple levels of type 14 references. Replace DEREF_* with
VAL_* which gets the value of a particular sequence element i.e.
Z%(A+1,1).
All together, the above changes save over 300 bytes.
Also:
- Fix empty nil/false/true entries so they
are treated the same as other types of data with regards to
reference counting and ALLOC/RELEASE.
- Add a new memory summary function in debug.in.bas that just prints
out free, value count, and references for the early scalar and empty
list elements. Comment out the larger one. This saves about 90
bytes.
2016-11-16 07:38:09 +03:00
|
|
|
R=R4
|
2016-11-19 08:51:33 +03:00
|
|
|
GOSUB INC_REF_R
|
2016-10-26 09:26:05 +03:00
|
|
|
GOTO ENV_GET_RETURN
|