ams-hackers / gbforth

👾 A Forth-based Game Boy development kit
https://gbforth.org
MIT License
121 stars 23 forks source link

Implement SLiteral and update PARSE #336

Closed tkers closed 2 years ago

tkers commented 2 years ago

Current behaviour PARSE ( -- addr u ) is defined to automatically write data into the ROM so the string is accessible at run-time. This means that words like s" and the derived ." can simply compile the 2 returned cells (addr and u) into the current word definition, and strings will work as expected.

Issues However, this behaviour of s" causes issues when using it top-level. For example when building a vector of strings like this:

CREATE vector
s" hello" mem,
s" world" mem,

: main
  vector     5 type   \ expect hello
  vector 5 + 5 type ; \ expect world

This code works in gforth, but gbforth duplicates the strings and starts appending them to the dictionary pointer which is unintended.

Solution Instead of having PARSE automatically move strings to the ROM, it should keep them in HOST memory until explicitly moved to the rom. In top-level code this can be done manually with a word like mem, (already implemented). The words s" and ." can be redefined to use SLiteral (not yet implemented) which compiles the string to the dictionary pointer, if used in a (target) colon definition. That means that this code still works correctly as before:

: main
  ." hello"
  s" world" type ;

But this will not:

s" hello" 2constant greet \ this contains a HOST address
: main
  greet type ; 

While mixing host/rom addresses can be confusing, the behaviour is consistent with gforth where strings are stored into transient memory, and need to be explicitly stored for later use.


tl;dr

Closes #70