refactor(v4.0.0): the capsule's inner words keep their state in memory

WORD, the dictionary words and the code generator run underneath
whatever the user has on the stacks, which are ten and nine deep (D-2).
Measured, they used five to seven data cells of their own, leaving a
line about three.  Each now keeps what it works on in its file's
scratch cells and has at most three cells on the data stack; , calls
nothing; and the longest chains of calls are shorter.

The public words of core.v4, input.v4 and dict.v4 get dictionary
headers.  NUMBER is split so the interpreter can have a flag instead of
NODE-ERROR.  The host-node tests share one memory map, host_map.h.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-04 10:41:50 -04:00
co-authored by Claude Opus 5.5
parent 44ffd261bb
commit bbd1b4047f
10 changed files with 360 additions and 248 deletions
+6 -33
View File
@@ -37,24 +37,8 @@ static int failures = 0, checks = 0;
#define CANARY ((v4_cell)0x0C0FFEE5)
#define MAXU ((v4_ucell)~(v4_ucell)0)
/* The memory map is open (D-4); the test puts everything at the top. */
#define TOP ((v4_cell)V4_NODE_WORDS)
#define NODE_ERROR (TOP - 2)
#define CONSOLE_TX (TOP - 4)
#define CONSOLE_RX (TOP - 6)
#define CONSOLE_ST (TOP - 7)
#define BASE (TOP - 8)
#define TO_IN (TOP - 9)
#define SPAN (TOP - 10)
#define PVARS (TOP - 16) /* six cells */
#define WBUF_W (TOP - 90) /* 65 cells = 260 bytes, with cells free on each side */
#define WBUF_CELLS 65
#define TIB_W (TOP - 360) /* 260 cells = 1040 bytes */
#define SBUF_W (TOP - 440) /* 64 cells = 256 bytes for the tests' own strings */
#define WBUF (WBUF_W * 4)
#define TIB (TIB_W * 4)
#define SBUF (SBUF_W * 4)
#define GUARD ((v4_cell)0x5EED5EED)
#include "host_map.h"
static v4_node n;
static v4_exec_state es;
@@ -226,21 +210,10 @@ int main(void)
printf("v4 host input tests: V4_CELL_BITS=%d, V4_NODE_WORDS=%u\n", V4_CELL_BITS, (unsigned)V4_NODE_WORDS);
v4_node_reset(&n);
v4_text_begin(&tx, &n, 16);
v4_text_constant(&tx, "N-1", V4_CELL_BITS - 1);
v4_text_constant(&tx, "NODE-ERROR", NODE_ERROR);
v4_text_constant(&tx, "CONSOLE-TX", CONSOLE_TX);
v4_text_constant(&tx, "CONSOLE-RX", CONSOLE_RX);
v4_text_constant(&tx, "CONSOLE-STATUS", CONSOLE_ST);
v4_text_constant(&tx, "BASE", BASE);
v4_text_constant(&tx, "TIB", TIB);
v4_text_constant(&tx, ">IN", TO_IN);
v4_text_constant(&tx, "SPAN", SPAN);
v4_text_constant(&tx, "WBUF", WBUF);
v4_text_constant(&tx, "(P)", PVARS);
CHECK(v4_text_assemble_file(&tx, V4_CAPSULE_DIR "/core.v4"), "core.v4 assembles: %s", v4_text_error(&tx));
CHECK(v4_text_assemble_file(&tx, V4_CAPSULE_DIR "/input.v4"), "input.v4 assembles: %s", v4_text_error(&tx));
{
static const char *const files[] = { "core.v4", "input.v4" };
CHECK(host_load(&tx, &n, files, 2), "the capsule assembles");
}
/* the in-line names, as words the test can call */
CHECK(v4_text_assemble(&tx, ": 'TIB TIB ; : '>IN >IN ; : 'SPAN SPAN ; : 'BL BL ;"), "wrappers: %s", v4_text_error(&tx));
CHECK(v4_text_finish(&tx), "everything is defined: %s", v4_text_error(&tx));
@@ -540,7 +513,7 @@ int main(void)
/* What they leave their caller (D-2). */
headroom("WORD", setup_line, 1, 32, 0, 0, 1, 3, 3);
headroom("NUMBER", setup_number, 1, SBUF, 0, 0, 2, 2, 3);
headroom("NUMBER", setup_number, 1, SBUF, 0, 0, 2, 2, 2);
headroom("EXPECT", setup_expect, 2, SBUF + 40, 20, 0, 0, 3, 4);
headroom("ENCLOSE", setup_number, 2, SBUF, 32, 0, 4, 2, 4);