fix(v4.0.0): shorter chains of calls in the compiler capsule

Measured, compiling a DO loop left one return entry spare under
INTERPRET and a defining word called from inside another word
overflowed the nine-entry return stack (D-2); the prompt loop will take
one more.

C@ and C! shift without a loop.  The code generator shifts each opcode
into the word being built, so nothing is placed by a counted shift, and
the address masks come from a table.  The dictionary search, the
in-liner, the end of a loop and the making of a data word are each one
word reached by a jump.

Every kind of line now leaves at least three return entries spare while
it compiles; a word run from the interpreter has six; and CREATE ...
DOES> works from the prompt, from a word, and from a word that calls
that.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-04 11:17:58 -04:00
co-authored by Claude Opus 5.5
parent dac7ffac92
commit 806f876ee0
9 changed files with 165 additions and 123 deletions
+7 -2
View File
@@ -753,8 +753,13 @@ built into the capsule:
- Every word of the capsule keeps what it works on in memory and has at most three cells of its own on
the data stack. Measured on the golden model: a line may have **6 values on the stack** while the
interpreter reads its next word, and defining and running a word leaves 4 cells under it untouched.
- Words called from the interpreter may nest **8 deep**; a `DO` loop takes two return entries, so two
nested loops leave four. `*` is therefore not `UM* drop` on the host node but N steps of `+*` with
- The capsule's words call each other as little as they can: byte access shifts without a loop,
opcodes are shifted into the word being built instead of placed by a counted shift, and the long
jobs (laying a loop's end, making a data word) are single words reached by a jump. Measured on the
golden model: a word run from the interpreter has **6 return entries** to itself, every kind of
line leaves at least 3 spare while it is compiled, and a defining word (`CREATE … DOES>`) works
from the prompt, from a word, and from a word that calls that. A `DO` loop takes two return
entries. `*` is therefore not `UM* drop` on the host node but N steps of `+*` with
only the count on the return stack; it gives the same low cell (what `+*` loses at the top of `T`
takes N shifts to reach the bit that moves into `A`, and the loop ends first).