feat(v4.0.0): vocabularies, to FORTH-79

- VOCABULARY DEFINITIONS CONTEXT CURRENT FORTH, and v3's ORDER.  A name is
  looked up in the CONTEXT vocabulary and then in FORTH; a new entry goes
  into the CURRENT vocabulary; : makes the CURRENT vocabulary CONTEXT;
  FORTH is immediate.
- WORDS lists the CONTEXT vocabulary.  FORGET takes what was defined later
  out of every vocabulary, and a vocabulary that goes gives way to FORTH.
- v3's vocabularies separate nothing: a word defined in one is found from
  every other, and one redefined in a vocabulary replaces FORTH's for good.
- tests/test_host_quit.c: isolation, chaining to FORTH, two vocabularies
  with the same names, FORGET across them; and DUMP is now checked to put
  BASE back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-05 07:18:28 -04:00
co-authored by Claude Opus 5.5
parent ab272cc2ad
commit 0fbe1432b7
6 changed files with 147 additions and 20 deletions
+3 -2
View File
@@ -714,7 +714,8 @@ it, `xt + 1`; for any other word the parameter field is the code itself.
| Word | Fate |
| --- | --- |
| `VOCABULARY` `DEFINITIONS` `CONTEXT` `CURRENT` `FORTH` `ORDER` `(FIND)` | CC |
| `VOCABULARY` `DEFINITIONS` `CONTEXT` `CURRENT` `FORTH` `ORDER` | CC | FORTH-79 (`ORDER` is v3's). Source in `v4/capsule/system.v4`, `dict.v4` and `compile.v4`. A vocabulary is two cells — its head, the xt of its newest entry, and the address of the vocabulary defined before it. `CONTEXT` and `CURRENT` each hold the address of a vocabulary's head cell; FORTH's is `(LATEST)`. A name is looked up in the `CONTEXT` vocabulary and then, if that is not FORTH, in FORTH ("new vocabularies chain to FORTH"). A new entry goes into the `CURRENT` vocabulary, and `:` makes the `CURRENT` vocabulary `CONTEXT`. `VOCABULARY xxx` makes an empty one whose name, executed, makes it `CONTEXT`; `FORTH` does the same for FORTH and is immediate; `DEFINITIONS` makes the `CONTEXT` vocabulary `CURRENT`. `WORDS` lists the `CONTEXT` vocabulary. `FORGET` takes what was defined later out of every vocabulary, and a vocabulary that goes with it gives way to FORTH. `ORDER` prints `Search order:` and `Current:` by name. v3's vocabularies do not separate anything: a word defined in one is found from every other, and a word redefined in one replaces FORTH's permanently; its `FORTH` is not immediate. Executed on the golden model's host node (2026-10-05). |
| `(FIND)` | CC | |
### 5.15 System
@@ -758,7 +759,7 @@ call would bury what it works on. A **compile-only** word may not be executed by
`v4/capsule/forth.v4` holds the first words of the vocabulary flagged this way (`DUP`, `+`, `>R`, `I`,
`LEAVE`, `@`, the in-line variables and so on).
**The vocabulary at the prompt.** The host node's capsule is `v4/capsule/`, loaded in this order: `core.v4` (bytes, console, strings the rest rest on), `input.v4`, `dict.v4`, `codegen.v4`, `compile.v4`, `quit.v4` (the prompt, faults and errors), `forth.v4` (stack, arithmetic, division, `DEPTH` `PICK` `ROLL`), `numout.v4` (number output, `.S`), `system.v4` (`WORDS`, `FORGET`), `qmath.v4` (the Q48.16 words of §5.26: `Q.FROM-INT Q.TO-INT Q.1 Q.0 Q.SCALE Q.+ Q.- Q.* Q./ Q.ABS Q.NEG Q.= Q.< Q.> Q.0= Q.MAX Q.MIN Q.EXP Q.SQRT Q.LOG Q.SIN Q.COS Q.PRINT`; `DUMP` is in `numout.v4`) and `words.v4` (the stack, comparison, shift, double, mixed and string words of §5.1–5.9: `2SWAP 2OVER 2ROT 2>R 2R> 2R@ 2@ 2! -! 0<> 0> <> <= >= U< U> ABS MAX MIN WITHIN LSHIFT RSHIFT D- DABS D0= D0< D= D2* D2/ D< DMAX DMIN M+ M- CMOVE> MOVE FILL ERASE BLANK -TRAILING COMPARE SEARCH SCAN SKIP ?TERMINAL TRUE FALSE INVERT NOP`). Each is the definition this document gives; `tests/test_host_quit.c` runs them from the prompt against transcripts of the v3 binary. From the prompt, 122 results of the Q words printed by `Q.PRINT` — which shows all sixteen bits of a fraction — are digit for digit v3's, at both cell widths. Under D-18, `Q./` by zero and `Q.SQRT` and `Q.LOG` outside their domain leave the result D-11 and D-12 give and then raise an error (codes 11 `Division by zero` and 12 `Argument out of range`); v3 returns 0 and says nothing. As v3, `LSHIFT` and `RSHIFT` with a count that is negative or as large as the cell is wide are an error (D-18, code 9, `Shift count out of range`). `M+`, like `M-` and `M/MOD`, takes its double in the standard order, low cell first; v3 takes it low cell on top.
**The vocabulary at the prompt.** The host node's capsule is `v4/capsule/`, loaded in this order: `core.v4` (bytes, console, strings the rest rest on), `input.v4`, `dict.v4`, `codegen.v4`, `compile.v4`, `quit.v4` (the prompt, faults and errors), `forth.v4` (stack, arithmetic, division, `DEPTH` `PICK` `ROLL`), `numout.v4` (number output, `.S`), `system.v4` (vocabularies, `WORDS`, `FORGET`), `qmath.v4` (the Q48.16 words of §5.26: `Q.FROM-INT Q.TO-INT Q.1 Q.0 Q.SCALE Q.+ Q.- Q.* Q./ Q.ABS Q.NEG Q.= Q.< Q.> Q.0= Q.MAX Q.MIN Q.EXP Q.SQRT Q.LOG Q.SIN Q.COS Q.PRINT`; `DUMP` is in `numout.v4`) and `words.v4` (the stack, comparison, shift, double, mixed and string words of §5.1–5.9: `2SWAP 2OVER 2ROT 2>R 2R> 2R@ 2@ 2! -! 0<> 0> <> <= >= U< U> ABS MAX MIN WITHIN LSHIFT RSHIFT D- DABS D0= D0< D= D2* D2/ D< DMAX DMIN M+ M- CMOVE> MOVE FILL ERASE BLANK -TRAILING COMPARE SEARCH SCAN SKIP ?TERMINAL TRUE FALSE INVERT NOP`). Each is the definition this document gives; `tests/test_host_quit.c` runs them from the prompt against transcripts of the v3 binary. From the prompt, 122 results of the Q words printed by `Q.PRINT` — which shows all sixteen bits of a fraction — are digit for digit v3's, at both cell widths. Under D-18, `Q./` by zero and `Q.SQRT` and `Q.LOG` outside their domain leave the result D-11 and D-12 give and then raise an error (codes 11 `Division by zero` and 12 `Argument out of range`); v3 returns 0 and says nothing. As v3, `LSHIFT` and `RSHIFT` with a count that is negative or as large as the cell is wide are an error (D-18, code 9, `Shift count out of range`). `M+`, like `M-` and `M/MOD`, takes its double in the standard order, low cell first; v3 takes it low cell on top.
**The stacks and the compiler.** The interpreter and compiler run on the same stacks as the user's
words, with the user's values beneath them. The capsule was written for stacks of ten cells and nine