feat(v4.0.0): the text assembler takes &NAME and CONST+N

&NAME is the address of a word as a literal; CONST+N is a loader
constant plus an offset as one literal, so that a capsule file can
address the cells of its scratch area without adding at run time.

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 26a6a16537
commit 44ffd261bb
3 changed files with 44 additions and 1 deletions
+15
View File
@@ -409,6 +409,21 @@ int main(void)
CHECK(ok(": 2DUP over over ; : 1+ 1 + ; : T ( a b -- 2a+2b+1 ) 2DUP + + + 1+ ;") && result("T", 2, 2, 3) == 11,
"names that begin with digits");
/* CONST+N: a constant and an offset as one literal */
CHECK(ok(": T VAR+3 ;") && result("T", 0, 0, 0) == VARS + 3, "CONST+N is the constant plus N");
CHECK(ok(": T VAR+0 VAR+10 + ;") && result("T", 0, 0, 0) == 2 * VARS + 10, "any N");
CHECK(nb.mem[ORIGIN + 1] == VARS && nb.mem[ORIGIN + 2] == VARS + 10, "and it is a single literal");
CHECK(ok(": VAR+1 77 ; : T VAR+1 ;") && result("T", 0, 0, 0) == 77, "a word of that very name comes first");
CHECK(refused(": T VAR+ ;", "never defined", 1) && refused(": T VAR+x ;", "never defined", 1) && refused(": T NOPE+1 ;", "never defined", 1),
"what is not a constant and a number is just an unknown name");
/* &NAME: a word's address as a literal */
CHECK(ok(": A 5 ; : T &A ;") && result("T", 0, 0, 0) == v4_text_word(&tx, "A"), "&NAME is the word's address");
CHECK(ok(": A 5 ; : T &A push ;") && result("T", 0, 0, 0) == 5, "which can be executed");
CHECK(refused(": T &A ; : A 5 ;", "already defined", 1), "the word must be defined first");
CHECK(refused(": T &VAR ;", "already defined", 1), "and be a word");
CHECK(refused(": &X 1 ;", "cannot be used as a name", 1), "a name cannot begin with &");
/* headers: a dictionary entry in front of a word (capsule/dict.v4) */
CHECK(ok("header DUP : (DUP) dup + ;"), "a header assembles: %s", v4_text_error(&tx));
{