1
1
mirror of https://github.com/kanaka/mal.git synced 2024-09-20 01:57:09 +03:00
Commit Graph

33 Commits

Author SHA1 Message Date
Joel Martin
7895453b77 Basic: various memory savings.
- simplify DO_CONCAT.
- inline MAL_READ/PRINT.
- comment out memory debug/sanity checks.
- more aggressive space removal.

Saves over 900 bytes.

Increase Z% value memory by 374 to 9216 (8192+1024).
2016-12-21 13:51:26 -07:00
Joel Martin
4202ef7bf1 Basic: miscellaneous memory savings.
- 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.
2016-11-18 23:51:33 -06:00
Joel Martin
d7a6c2d6c9 Basic: refactor memory layout.
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).
2016-11-18 01:26:23 -06:00
Joel Martin
9d59cdb384 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-15 23:00:57 -06:00
Joel Martin
037815e0f3 Basic: more reductions. RELEASE refactor.
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.
2016-11-10 01:51:02 -06:00
Joel Martin
f9f1cec9cc Basic: memory savings and variable simplifications.
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.
2016-11-06 17:29:11 -06:00
Joel Martin
935930128c Basic: move logic/release stack to $C000
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.
2016-11-04 21:46:45 -05:00
Joel Martin
c756af8196 Basic: reduce variables. Fix func printing.
- 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.
2016-11-04 00:07:09 -05:00
Joel Martin
6420f327cd Basic: add string memory mgt. Fix eval, symbol fns 2016-11-03 23:27:42 -05:00
Joel Martin
4fab6aa517 Basic: more memory savings
- 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.
2016-11-02 23:36:44 -05:00
Joel Martin
259dd13c56 Basic: more aggressive space removal
Saves over 1200 bytes so that Z% value space can be bumped up by 256
entries.
2016-11-02 22:19:51 -05:00
Joel Martin
0197588627 Basic: add QBasic support.
make MODE=qbasic stepA_mal.bas
qb64 stepA_mal.bas
2016-10-30 19:15:24 -05:00
Joel Martin
4e7d8a1bcf Basic: fix step6 arg test. Gensym. Misc cleanup.
- Strip linefeeds in run_argv_test.sh so that step6 arg test passes
  for basic.
- Add gensym and convert or macro.
- Add gitignore entries for transpiled basic sources.
- Add conj/seq stubs so that step4 self-host loads (if non-step4
  functions are commented out in core.mal)
- Bump up Z% value space by 256 spaces (1K)
- Remove old qb2cbm.sh
2016-10-28 00:09:56 -05:00
Joel Martin
c7330b3d69 Basic: fix errors, reader, if form. Self-host 0-3
- Stop let binding eval on error. Also don't continue into EVAL if
  error.
- if without a false position was freeing up too much when it
  finished.
- fix reader so that it doesn't keep incrementing ref cnt of static
  empty sequences.
2016-10-26 22:29:09 -05:00
Joel Martin
de2f4de9b8 Basic: use static empty sequences in reader.
- Add vector and hash-map empty static sequences in types
2016-10-26 20:43:17 -05:00
Joel Martin
01e8850d43 Basic: Reduce GOSUB use. Partial self-host to step3
step4 runs out of space attempting to load the program. Step2 and
step3 run out of memory (stack exhaustion) for more complicated forms.

- Use GOTO with return label on our stack instead of GOSUB for:
    - APPLY function in types.in.bas
    - "apply", "map" and "swap!" core functions
- Implement DO TCO. Change EVAL_AST to detect if we are called from DO
  and exit one element early.
- Remove GOSUB recursion from EQUAL_Q
- Inline PAIR_Q. Reduce REPLACE stack use.
- Remove one level of GOSUB/stack by calling REP with GOTO
- Simplify mal/step2_eval.mal to remove use of (or ) macro in
  eval_ast.
- Fix ON GOTO/GOSUB line detection in basicpp
2016-10-24 23:29:27 -05:00
Joel Martin
0e508fa518 Basic: add read-file. Misc basicpp space savings.
- Add read-file which is similar to read-string but from a file name
  rather than a string. This allows steps 0-2 to load although each
  one eventuall crashes with out of memory after evaluating "123"
  a few times.
- basicpp:
    - Renumber the line numbers so they are ordinally increasing. This
      saves 150 or so bytes because GOTO/GOSUB calls have smaller line
      numbers.
    - Shrink 'IF 123' -> 'IF123' for almost 300 byte savings.[:w
    - Simplify PR_MEMORY_SUMMARY output. Save 75 bytes
- Add missing runtest.py change that allows basic tests to pass.
2016-10-23 22:18:08 -05:00
Joel Martin
bbab5c5d38 Basic: hashmap functions. Basic metadata (on funcs)
- Metadata support required expanding the type size (to 5 bits). This
  also implies that ref cnt now only has 11 bits (2048).
- Added ^ reader macro (with-meta) which required some refactoring of
  READ_MACRO to share code.
- Rename some more variables:
    ZJ  -> S
    S%  -> X%
    ZR% -> Y%
    ZM% -> Y
    RE% -> D
  This removes remaining % variables apart from the pre-allocated
  arrays Z%, S% and X%.
2016-10-22 16:11:46 -05:00
Joel Martin
a742287e0e Basic: smarter ALLOC. Keywords. Vector fixes.
- Modify ALLOC to take a type (rather than size) and take default
  values to set for the 1-3 values/pointers. Let alloc do the
  ownership taking of the referred values when appropriate.
- Add FORCE_SEQ_TYPE function to coerce sequence to given type. Fixes
  apply and rest on vector. Simplifies concat.
- Use a double ON GOTO structure for calling the native functions in
  DO_FUNCTION.
- Add some stub core functions.
- Move CHECK_FREE_LIST to debug.in.bas
- All changes together save over 1K
2016-10-14 23:48:03 -05:00
Joel Martin
cc9dbd92e3 Basic: variable renaming. Save 2 kbytes.
Also, add variables.txt file with start of documenting meanings of
variables.

List of renamings/savings:

ZZ%   -> S%   : 131 bytes
ZL%   -> X    : 550 bytes
A%    -> A    : 192 bytes
E%    -> E    :  32 bytes
R%    -> R    : 381 bytes
AR%   -> AR   :  30 bytes
AY%   -> AY   :  71 bytes
AZ%   -> AZ   :  33 bytes
B%    -> B    :  47 bytes
AA%   -> AA   :  64 bytes
AB%   -> AB   :  25 bytes
F%    -> F    :  21 bytes
FF%   -> FF   :  14 bytes
ER%   -> ER   :  41 bytes
PR%   -> PR   :   7 bytes
T%    -> T    :  46 bytes
R0-9% -> R0-9 :  31 bytes
T0-9% -> T0-9 :  42 bytes
S1-4% -> S1-4 :  25 bytes
U0-9% -> U0-9 :  44 bytes
ZK%   -> ZK   :  10 bytes
ZI%   -> ZI   :  10 bytes
RC%   -> RC   :  16 bytes
K%/V% -> K/V  :  21 bytes
SD%   -> SD   :  16 bytes
ZS$   -> S$   :  40 bytes
HM%   -> H    :  10 bytes
SZ%   -> SZ   :  39 bytes
LV%   -> LV   :   9 bytes
EO%   -> O    :  18 bytes
C%    -> C    :   4 bytes
P%    -> P    :   4 bytes
2016-10-14 22:42:56 -05:00
Joel Martin
5e5ca0d438 Basic: step9 basics
- Change ER% to be -2 for no error, -1 for raw string error, and >=0
  as pointer to an error object.
2016-10-08 23:41:33 -05:00
Joel Martin
70f29a2b3c Basic: step8 basics. Fix def!, let*, concat, scalars.
- Move apply logic in swap! to APPLY function in types and use that
  for macroexpand
- Abort def! if error before updating the environment
- let* wasn't properly saving A2% for the final eval. Also, the
  environment release check should be against the top-level EVAL env,
  not the root repl env.
- (concat (list) ...) was broken so fix it to ignore empty lists that
  aren't in the trailing position.
- nil, false and true in the reader were always being returned as
  references (with an ref cnt) but we have the assumption that
  references (14) are not ref cnt'd and are always part of a compound
  type so fix the reader to just return the interned addresses.
2016-10-06 22:22:57 -05:00
Joel Martin
60ef223c3c Basic: basicpp adds, other misc. Shaves 3031 bytes.
- basicpp.py:
    - Fix "ON GOTO/GOSUB" label replacment
    - Add combine line capability
    - Change "THEN GOTO" to "THEN"
- Remove some spaces and unnecessary parens
- Restructure several places with multiple "GOTO/GOSUBs" statements
  into fewer "ON GOTO/GOSUB" statements
2016-09-23 22:36:17 -05:00
Joel Martin
9e8f521118 Basic: step7 basics, reader macros. step1,3 tests.
Also:
- Add some step1 and step3 tests that were discovered during Basic
  development.
- Move PR_MEMORY* to debug.in.bas
- Simplify Makefile deps
- Fix freeing in steps4-7 when error at deeper level
  i.e. (prn (abc))
- add SLICE function to support concat implementation.
2016-09-21 23:27:12 -05:00
Joel Martin
bf8d1f7d6c Basic: reduce memory usage by 614 bytes.
- combine some lines
- remove some unnecessary spaces and parens
- add string allocations to single routine in types

Also:
- remove blank lines in qb2cbm.sh output (does not save memory)
2016-09-20 21:11:46 -05:00
Joel Martin
85d70fb791 Basic: step6 basics and atoms. Fix strings.
Also:
- command lines arguments are implemented by creating a file
  ".args.mal" that contains a list of arguments and that is loaded by
  the run script (load-file) into -*ARGS*-. The rest is put in *ARGV*
  and the first element is pulled out and used as the script name.
- fix string reading/printing using new REPLACE function
- add RE function to skip printing and to get back evaluated value
  (result must be freed by caller). Needed for step6 to get first
  argument pointer for scripting.
- Sync earlier steps
- add cons, first, rest to support parsing the command line.
- eval is implemented as standard function in core.in.mal
- fix println bug (using PR_STR rather than PR_STR_SEQ)
- change sequence printing to save the initial sequence type on the
  stack and use that for the ending sequence delimeter. This way
  sequences of one type can still use the tail of sequences of
  a different type but still be considered the initial type.
2016-09-19 21:23:21 -05:00
Joel Martin
412e7348e3 Basic: add step5, fix recursive/error memory issues.
- Add TCO recur to let*
- Release of all memory from recursive function and let* calls.
- Fix a number of cases of trying to release already freed memory.
- Print function in memory as 2 byte unit rather than two separate
  memory locations.
2016-09-17 23:03:30 -05:00
Joel Martin
4b84a23b07 Basic: Add memory management. More step4.
Also:
- More/better detail in PR_MEMORY/PR_MEMORY_SUMMARY
- Fix *.prg image build (for running under Vice). Have to lower-case
  everything since what C64/Vice shows as capitals are actually
  lowercase.
2016-09-16 01:00:58 -05:00
Joel Martin
60270667b0 Basic: move environment into normal memory. 2016-09-15 23:58:55 -05:00
Joel Martin
241d5d574a Basic: most of step4. 2016-09-11 21:36:15 -05:00
Joel Martin
0cb556e024 Basic: add step3, vector/hash-map evaluation.
Also:
- qb2cbm.sh: Add KEEP_REM level variable to tweak which REM/comments
  are emitted/skipped.
- fix printer issue with recursive sequences after evaluation (with
  refeerences in them)
- add stats target
2016-09-11 00:11:55 -05:00
Joel Martin
b7b1787f83 Basic: step2 basics. Vectors and hash-maps.
Adjust step2 tests to keep values within 2 byte int range.
2016-09-10 22:13:27 -05:00
Joel Martin
11f94d2e74 Basic: step1 basics. 2016-09-04 20:42:50 -05:00