feat(v4): the ROM's symbol table

(FIND) ( -- rec | 0 ), (DEFINE) ( value kind -- ) and (OPCODE) ( -- op | -1 ),
entries 3-5.  Names are refused as text.c's define refuses them, compared
case by case with text.c; a set variable may be set again.  256 hash heads,
records growing up and names growing down in dictionary space, used only
while the ROM assembles.  text.c gains the data directives #, and ", (the
ROM's language; its mnemonic and reserved-word tables are data); the
nucleus image is byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-15 11:54:15 -04:00
co-authored by Claude Opus 5.5
parent 080811dbd2
commit 07911dcf91
9 changed files with 404 additions and 13 deletions
+22
View File
@@ -499,6 +499,28 @@ int main(void)
CHECK(refused("constant K x", "not a number", 1), "a constant's value is a number");
CHECK(refused(": constant ;", "cannot be used as a name", 1), "constant is reserved");
/* ---- `#, VALUE` and `", TOKEN`, data in the text (the ROM's language) ---- */
{
v4_ucell ab = 2u | ((v4_ucell)'a' << 8) | ((v4_ucell)'b' << 16), paren = 1u | ((v4_ucell)'(' << 8);
v4_ucell five_l = 5u | ((v4_ucell)'a' << 8) | ((v4_ucell)'b' << 16) | ((v4_ucell)'c' << 24);
v4_ucell five_h = (v4_ucell)'d' | ((v4_ucell)'e' << 8);
CHECK(ok("constant K 9 : T ; #, 5 #, -1 #, K #, K+2 #, &T \", ab \", ( \", abcde"),
"data assembles: %s", v4_text_error(&tx));
CHECK(nb.mem[ORIGIN + 1] == 5 && nb.mem[ORIGIN + 2] == -1 && nb.mem[ORIGIN + 3] == 9 && nb.mem[ORIGIN + 4] == 11
&& nb.mem[ORIGIN + 5] == ORIGIN, "#, lays a number, a constant, CONST+N and &NAME");
CHECK((v4_ucell)nb.mem[ORIGIN + 6] == ab && (v4_ucell)nb.mem[ORIGIN + 7] == paren,
"\", lays a counted string, padded to a whole cell; ( is a name here");
CHECK((v4_ucell)nb.mem[ORIGIN + 8] == five_l && (v4_ucell)nb.mem[ORIGIN + 9] == five_h && v4_text_here(&tx) == ORIGIN + 10,
"a longer one runs on into the next cell");
CHECK(ok(": T dup #, 7 ;") && nb.mem[ORIGIN + 1] == 7 && v4_text_word(&tx, "T") == ORIGIN,
"#, inside a word ends the instruction word first");
CHECK(refused("#, x", "not a value", 1), "#, needs a value");
CHECK(refused("#,", "#, without a value", 1), "#, at the end");
CHECK(refused("\",", "\", without a string", 1), "\", at the end");
CHECK(refused(": #, ;", "cannot be used as a name", 1) && refused(": \", ;", "cannot be used as a name", 1),
"#, and \", are reserved");
}
CHECK(v4_node_guards_intact(&na) && v4_node_guards_intact(&nb), "guards intact");
printf(" %d checks, %d failures\n", checks, failures);