1
1
mirror of https://github.com/kanaka/mal.git synced 2024-09-21 10:37:58 +03:00
mal/basic/reader.in.bas

261 lines
7.2 KiB
QBasic
Raw Normal View History

REM READ_TOKEN(RF=0, A$, RI) -> T$
REM READ_TOKEN(RF=1) -> T$
2016-09-05 04:42:50 +03:00
READ_TOKEN:
IF RF=1 THEN RF=2:T$="(":RETURN
IF RF=2 THEN RF=3:T$="do":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
GOSUB SKIP_SPACES
REM PRINT "READ_TOKEN: "+STR$(RI)+", "+MID$(A$,RI,1)
GOSUB READ_CHAR
IF C$=";" THEN GOSUB SKIP_TO_EOL:GOTO READ_TOKEN
T$=C$
IF T$="(" OR T$=")" OR T$="[" OR T$="]" OR T$="{" OR T$="}" OR T$="'" OR T$="`" OR T$="@" THEN RETURN
GOSUB PEEK_CHAR: REM peek at next character
IF T$="~" AND C$<>"@" THEN RETURN
S1=0:S2=0: REM S1: INSTRING?, S2: ESCAPED?
IF T$=CHR$(34) THEN S1=1
2016-09-05 04:42:50 +03:00
READ_TOKEN_LOOP:
GOSUB PEEK_CHAR: REM peek at next character
IF C$="" THEN RETURN
2016-09-05 04:42:50 +03:00
IF S1 THEN GOTO READ_TOKEN_CONT
IF C$=" " OR C$="," OR C$=CHR$(13) OR C$=CHR$(10) THEN RETURN
IF C$="(" OR C$=")" OR C$="[" OR C$="]" OR C$="{" OR C$="}" THEN RETURN
2016-09-05 04:42:50 +03:00
READ_TOKEN_CONT:
GOSUB READ_CHAR
T$=T$+C$
IF T$="~@" THEN RETURN
IF S1=0 OR S2=1 THEN S2=0:GOTO READ_TOKEN_LOOP
REM S1=1 (INSTRING?) and S2=0 (not ESCAPED?)
IF C$=CHR$(92) THEN S2=1
IF C$=CHR$(34) THEN RETURN
2016-09-05 04:42:50 +03:00
GOTO READ_TOKEN_LOOP
REM READ_CHAR(A$, RI) -> C$
READ_CHAR:
RJ=1:GOSUB DO_READ_CHAR
RETURN
REM PEEK_CHAR(A$, RI) -> C$
PEEK_CHAR:
RJ=0:GOSUB DO_READ_CHAR
RETURN
REM DO_READ_CHAR(RJ, A$, RI):
REM - RI is position in A$
REM - RJ=1 is read, RJ=0 is peek
DO_READ_CHAR:
C$=""
IF RF>0 THEN GOTO READ_FILE_CHAR
IF RI<=LEN(A$) THEN C$=MID$(A$,RI,1):RI=RI+RJ
RETURN
REM READ_FILE_CHAR(RJ) -> C$
REM - RJ=1 is read, RJ=0 is peek
REM - D$ is global used for already read pending character
REM - EZ is global used for end of file state
READ_FILE_CHAR:
IF D$<>"" THEN C$=D$:IF RJ=0 THEN RETURN
IF D$<>"" AND RJ=1 THEN D$="":RETURN
D$=""
IF EZ>2 THEN C$=""
IF EZ=2 THEN C$=")"
IF EZ=1 THEN C$=CHR$(10)
IF EZ>0 THEN EZ=EZ+RJ:RETURN
#cbm GET#2,C$
#qbasic C$=INPUT$(1,2)
#qbasic IF EOF(2) THEN EZ=1:RETURN
IF RJ=0 THEN D$=C$
#cbm IF (ST AND 64) THEN EZ=1:RETURN
#cbm IF (ST AND 255) THEN EZ=1:ER=-1:E$="File read error"+STR$(ST)
RETURN
2016-09-05 04:42:50 +03:00
SKIP_SPACES:
GOSUB PEEK_CHAR: REM peek at next character
IF C$=" " OR C$="," OR C$=CHR$(13) OR C$=CHR$(10) THEN GOSUB READ_CHAR:GOTO SKIP_SPACES
RETURN
2016-09-05 04:42:50 +03:00
SKIP_TO_EOL:
GOSUB READ_CHAR
IF C$="" OR C$=CHR$(13) OR C$=CHR$(10) THEN RETURN
GOTO SKIP_TO_EOL
2016-09-05 04:42:50 +03:00
REM READ_FORM(A$, RI, RF) -> R
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
SUB READ_FORM
Q=T:GOSUB PUSH_Q: REM save current value of T
READ_FORM_RECUR:
IF ER<>-2 THEN GOTO READ_FORM_RETURN
2016-09-05 04:42:50 +03:00
GOSUB READ_TOKEN
REM PRINT "READ_FORM T$: ["+T$+"]"
IF T$="" THEN R=0:GOSUB INC_REF_R:GOTO READ_FORM_RETURN
IF T$="nil" THEN T=0:GOTO READ_NIL_BOOL
IF T$="false" THEN T=1:GOTO READ_NIL_BOOL
IF T$="true" THEN T=2:GOTO READ_NIL_BOOL
IF T$="'" THEN B$="quote":GOTO READ_MACRO
IF T$="`" THEN B$="quasiquote":GOTO READ_MACRO
IF T$="~" THEN B$="unquote":GOTO READ_MACRO
IF T$="~@" THEN B$="splice-unquote":GOTO READ_MACRO
IF T$="^" THEN B$="with-meta":GOTO READ_MACRO
IF T$="@" THEN B$="deref":GOTO READ_MACRO
C$=MID$(T$,1,1)
REM PRINT "C$: ["+C$+"]("+STR$(ASC(C$))+")"
IF C$>="0" AND C$<="9" THEN GOTO READ_NUMBER
IF C$="-" THEN GOTO READ_SYMBOL_MAYBE
IF C$=CHR$(34) THEN GOTO READ_STRING
IF C$=":" THEN GOTO READ_KEYWORD
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
REM set end character in Q and read the sequence
IF C$="(" THEN T=6:Q=41:GOTO READ_SEQ_START: REM ")"
IF C$="[" THEN T=7:Q=93:GOTO READ_SEQ_START: REM "]"
IF C$="{" THEN T=8:Q=125:GOTO READ_SEQ_START: REM "}"
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 C$=")" OR C$="]" OR C$="}" THEN R=-1:ER=-1:E$="unexpected "+C$:GOTO READ_FORM_RETURN
2016-09-05 04:42:50 +03:00
GOTO READ_SYMBOL
READ_NIL_BOOL:
REM PRINT "READ_NIL_BOOL"
R=T*2
GOSUB INC_REF_R
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
GOTO READ_FORM_RETURN
2016-09-05 04:42:50 +03:00
READ_NUMBER:
REM PRINT "READ_NUMBER"
T=2:L=VAL(T$):GOSUB ALLOC
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
GOTO READ_FORM_RETURN
READ_MACRO:
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
REM push macro type
Q=-1*(T$="^"):GOSUB PUSH_Q
REM B$ is set above
T=5:GOSUB STRING
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
REM push string
GOSUB PUSH_R
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
CALL READ_FORM
REM push first form
GOSUB PUSH_R
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 ER>-2 THEN GOTO READ_MACRO_DONE
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
GOSUB PEEK_Q_2
IF Q THEN GOTO READ_MACRO_3
READ_MACRO_2:
GOSUB PEEK_Q_1:B=Q
GOSUB PEEK_Q:A=Q
GOSUB LIST2
GOTO READ_MACRO_DONE
READ_MACRO_3:
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
CALL READ_FORM
GOSUB PEEK_Q_1:C=Q
B=R
GOSUB PEEK_Q:A=Q
GOSUB LIST3
AY=C:GOSUB RELEASE
READ_MACRO_DONE:
REM release values, list has ownership
AY=B:GOSUB RELEASE
AY=A:GOSUB RELEASE
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
REM pop the stack
GOSUB POP_Q: REM pop first form
GOSUB POP_Q: REM pop string
GOSUB POP_Q: REM pop macro type
T$="": REM necessary to prevent unexpected EOF errors
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
GOTO READ_FORM_RETURN
2016-09-05 04:42:50 +03:00
READ_STRING:
REM PRINT "READ_STRING"
C=ASC(MID$(T$,LEN(T$),1))
IF C<>34 THEN R=-1:ER=-1:E$="expected '"+CHR$(34)+"', got EOF":GOTO READ_FORM_RETURN
R$=MID$(T$,2,LEN(T$)-2)
S1$=CHR$(92)+CHR$(92):S2$=CHR$(127):GOSUB REPLACE: REM protect backslashes
S1$=CHR$(92)+CHR$(34):S2$=CHR$(34):GOSUB REPLACE: REM unescape quotes
#cbm S1$=CHR$(92)+"n":S2$=CHR$(13):GOSUB REPLACE: REM unescape newlines
#qbasic S1$=CHR$(92)+"n":S2$=CHR$(10):GOSUB REPLACE: REM unescape newlines
S1$=CHR$(127):S2$=CHR$(92):GOSUB REPLACE: REM unescape backslashes
2016-09-12 05:36:15 +03:00
REM intern string value
B$=R$:T=4:GOSUB STRING
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
GOTO READ_FORM_RETURN
READ_KEYWORD:
R$=CHR$(127)+MID$(T$,2,LEN(T$)-1)
B$=R$:T=4:GOSUB STRING
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
GOTO READ_FORM_RETURN
READ_SYMBOL_MAYBE:
C$=MID$(T$,2,1)
IF C$>="0" AND C$<="9" THEN GOTO READ_NUMBER
2016-09-05 04:42:50 +03:00
READ_SYMBOL:
REM PRINT "READ_SYMBOL"
B$=T$:T=5:GOSUB STRING
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
GOTO READ_FORM_RETURN
2016-09-05 04:42:50 +03:00
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
READ_SEQ_START:
SD=SD+1
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
GOSUB PUSH_Q: REM push return character
REM setup the stack for the loop, T has type
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
GOSUB MAP_LOOP_START
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
READ_SEQ_LOOP:
REM TODO: reduce redundancy with READ_TOKEN
GOSUB SKIP_SPACES
GOSUB PEEK_CHAR: REM peek at next character
IF C$="" THEN ER=-1:E$="unexpected EOF":GOTO READ_SEQ_DONE
IF C$=";" THEN GOSUB SKIP_TO_EOL:GOTO READ_SEQ_LOOP
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
Q=3:GOSUB PEEK_Q_Q
IF C$=CHR$(Q) THEN GOSUB READ_CHAR:GOTO READ_SEQ_DONE
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
CALL READ_FORM
M=R: REM value (or key for hash-maps)
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
REM if error, release the unattached element
IF ER<>-2 THEN AY=R:GOSUB RELEASE:GOTO READ_SEQ_DONE
REM if this is a hash-map, READ_FORM again
IF T=8 THEN GOSUB PUSH_R:CALL READ_FORM
IF T=8 THEN N=R:GOSUB POP_Q:M=Q: REM set key and value
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
REM update the return sequence structure
REM release N since list takes full ownership
C=1:GOSUB MAP_LOOP_UPDATE
GOTO READ_SEQ_LOOP
2016-09-05 04:42:50 +03:00
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
READ_SEQ_DONE:
SD=SD-1
REM cleanup stack and get return value
GOSUB MAP_LOOP_DONE
2016-09-05 04:42:50 +03:00
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
GOSUB POP_Q: REM pop end character ptr
GOTO READ_FORM_RETURN
2016-09-05 04:42:50 +03:00
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
READ_FORM_RETURN:
GOSUB POP_Q:T=Q: REM restore current value of T
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
END SUB
REM READ_STR(A$) -> R
2016-09-05 04:42:50 +03:00
READ_STR:
RI=1: REM index into A$
RF=0: REM not reading from file
SD=0: REM sequence read depth
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
CALL READ_FORM
2016-09-05 04:42:50 +03:00
RETURN
REM READ_FILE(A$) -> R
READ_FILE:
RF=1: REM reading from file
EZ=0: REM file read state (1: EOF)
SD=0: REM sequence read depth
D$="": REM pending read/peek character
#cbm OPEN 2,8,0,A$
#qbasic IF NOT _FILEEXISTS(A$) THEN ER=-1:E$="File not found":RETURN
#qbasic OPEN A$ FOR INPUT AS #2
REM READ_TOKEN adds "(do ... )"
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
CALL READ_FORM
CLOSE 2
EZ=0
RETURN