Use a one dimensional array for the Z% value array. This enables
lists, vectors, environments and metadata pointers to all save off
1 word (2 bytes) of space.
Split the memory init and functions into mem.in.bas.
In addition, change type 14 to be metdata rather than any type 16-31.
This change saves about 560 bytes (no second array dimension
subscripts) and reduces Z% value usage by 10%-15%.
Bump the number of Z% words by 200 (to 8591). This enables
self-hosting up to step7 (without step8-stepA functions in core.mal).
- 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.
Save about 400 bytes.
Increase value Z% array by 100 to 4195.
Reduce string array by 1 (to 199) since in BASIC the value is the last
index not the size.
In core move incrementing of function index into
INIT_CORE_SET_FUNCTION. Switch 3 IF GOTO to ON GOTO. Reuse some
temporary variables.
Saves about 480 bytes.
Bump value array from 3950 to 4096. This allows step4 (sumdown 2) to
pass. Previously only (sumdown 1) passed.
Uses stack PUSH*/POP*/PEEK* routines instead of direct X% and Y%
access. Seems to be about the same performance (maybe a 5% performance
hit at most).
This gives us a larger stack (1920 2-byte words of $C000 rather
than 200 words as before). The release stack at $CF00 stays the same
size (64 4-byte addr/level entries).
Also saves over 1K or program and array space. So take the opportunity
to expand Z% entry space from 3712 to 3950.
- Save over 450 bytes. Bump up Z values by 128.
- Fix function printing when function is embedded in something else by
using strings storage as a stack while printing rather than using
RR$
- Simplify some error messages and sanity checks in RELEASE.
- Do the pop of CALL return value at the end of the subroutine
(callee) rather than at the call point (caller)
- shorten some character variables (CH$->C$, CH->C)
- remove spaces after OPEN, GET
- print REPL header directly in BASIC code
Together saves 404 bytes of memory.
($ _SERVER) returns a mal hash-map holding the contents of the $_SERVER superglobal from PHP.
(! file_get_contents "https://github.com") returns a string containing the github homepage.
file_get_contents is a native PHP function.