A v4 node no longer reads its own command line or prints a prompt. Its host puts a line of text in the node's input buffer and starts it at (LINE); the node interprets it and stops at (IDLE), leaving in (LINE-STATUS) how it ended: completed, an error, or QUIT. The host says " ok" or " ERROR" and prompts, as the kernel's REPL does for a v3 VM. A line may be 1024 characters, a block, as v3's. Ruled 2026-10-05 (V3-PARITY.md 1b); design ENGINE.md 3.1. - quit.v4: (REPL), the node's prompt loop, is gone; (LINE) (IDLE) (DONE) - image.h/.c: v4_line_begin, v4_line_done, v4_line_status; the node is idle at switch-on - boot.c: v4_boot_line, the one loop the hosted binary, the kernel and the capsule loader hand a line with; the code that took " ok" and the prompt back out of the node's output is gone - hosted.c, sk_v4.c: the prompt and the line editing are the host's - test_host_quit.c: the tests are the node's host; two tests of the old 80-character prompt line now test a whole line, 1024 and 1025 characters Verified: make -C v4 test passes at both widths; hosted-check passes on three ISAs; clean qemu with STARFORTH_V4=1 on amd64, aarch64 and riscv64 passes POST (550 of 550) with the same hashes as hosted, and three lines typed at each bare-metal prompt through the serial port are answered correctly (logs/20261005-180922, -181152, -181541). Still the lone node: kernel_main.c starts it before the fleet tables. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
124 lines
6.0 KiB
Markdown
124 lines
6.0 KiB
Markdown
# v4/
|
|
|
|
StarForth v4: the 32-instruction F18-derived core. The design lives in
|
|
`docs/v4.0.0/JUSTIFICATION.md` (why) and `docs/v4.0.0/DECOMPOSITION.md`
|
|
(every v3 word mapped to a v4 fate).
|
|
|
|
The first deliverable is the hosted C99 golden model (`JUSTIFICATION.md` §10,
|
|
step 1). It must pass POST and hold K≡1.0 with 32- and 64-bit cells on all
|
|
three host ISAs.
|
|
|
|
Acceptance (`JUSTIFICATION.md` §16): v4 must be equivalent to v3 at any point
|
|
in time, with the same vocabularies and behaviour, on the F18-derived engine;
|
|
and every ISA, hosted and bare metal, must still reach its `ok` prompt.
|
|
`make -C v4 test` passing is a development check, not acceptance.
|
|
|
|
What exists so far is the single node: registers, circular stacks, memory, all
|
|
32 opcodes, per-opcode and per-call-target heat, and three console
|
|
registers (`CONSOLE-TX`, which captures output, and `CONSOLE-RX` and `CONSOLE-STATUS`, which hand out
|
|
input a test feeds) standing in for the console node until the mesh exists. The tests load definitions
|
|
onto a node either opcode by opcode (`v4/include/v4/asm.h`) or as text in the notation `DECOMPOSITION.md`
|
|
uses (`v4/include/v4/text.h`). `make -C v4 test` builds
|
|
and runs the tests at both cell widths; `make -C v4 sanitize` repeats them
|
|
under ASan and UBSan. There is no POST and no K measurement yet.
|
|
|
|
## The system: nucleus, capsules, prompt
|
|
|
|
`docs/v4.0.0/NUCLEUS.md` is the design. A v4 system is four things:
|
|
|
|
| Part | Where | What it is |
|
|
|---|---|---|
|
|
| Engine | `v4/src` | The golden model of the 32-opcode node |
|
|
| Nucleus | `v4/capsule/*.v4`, built by `v4/tools/mkimage.c` | The assembled words, as a memory image linked into the binary |
|
|
| Capsules | `capsules/v4/*.4th`, baked by `tools/mkcapsule.c` | FORTH source, loaded when the system comes up |
|
|
| Boot | `v4/system/boot.c` | Starts the nucleus, checks and loads each capsule, prints the parity lines, gives the prompt |
|
|
|
|
Two products link the same four and differ only in the console:
|
|
|
|
- **Hosted Linux**, `v4/tools/hosted.c`: `make -C v4 hosted` builds
|
|
`v4/build/starforth4-amd64`, `-aarch64` and `-riscv64`, static, 64-bit cells.
|
|
- **Bare metal**, `kernel/src/v4/sk_v4.c`: `make -f kernel/Makefile ARCH=<arch> STARFORTH_V4=1`.
|
|
|
|
A boot prints:
|
|
|
|
```
|
|
PARITY:V4_NUCLEUS words=292 image_hash=0x...
|
|
PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x... capsule_hash=0x... dict_hash=0x...
|
|
PARITY:OK
|
|
ok>
|
|
```
|
|
|
|
Every build of one commit prints the same hashes. `make -C v4 hosted-check`
|
|
boots the three hosted binaries (the two foreign ones under user-mode QEMU)
|
|
and fails unless their output is identical and ends in `PARITY:OK`.
|
|
|
|
A capsule line the node does not answer ` ok` to ends the boot, naming the
|
|
capsule, block and line, with `PARITY:FAIL` and `POST: FAILED`.
|
|
|
|
State, 2026-10-05, after `ENGINE.md` step 1: all six builds start the nucleus,
|
|
load `v4:forth79.4th`, pass POST and reach `ok>`, with the same lines:
|
|
|
|
```
|
|
PARITY:V4_NUCLEUS words=295 image_hash=0x3b5a9a7a2f7c5361
|
|
PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=... dict_hash=0xc45c4db43ea0b1f1
|
|
PARITY:V4_POST tests=550 pass=550 fail=0
|
|
PARITY:V4_CAPSULE name=v4:post79.4th capsule_id=... dict_hash=0x88df0873060da73e
|
|
PARITY:OK
|
|
POST: PASSED
|
|
ok>
|
|
```
|
|
|
|
Bare-metal logs: `logs/20261005-180922/amd64/`, `logs/20261005-181152/aarch64/`,
|
|
`logs/20261005-181541/riscv64/`. On each, three lines were then typed at the
|
|
prompt through the serial port — a definition, its use with the capsule's
|
|
`U*`, and an unknown word — and each answered as the hosted binary does. The
|
|
capsules were unsigned (no signing key on this machine).
|
|
|
|
**A node is handed a line** (`docs/v4.0.0/ENGINE.md` 3.1). It does not read
|
|
its own command line and prints no prompt. Its host puts the text in the
|
|
node's input buffer and starts it at `(LINE)`; the node interprets the text
|
|
and stops at `(IDLE)`, leaving in `(LINE-STATUS)` how it ended. The host says
|
|
` ok` or ` ERROR` and prompts, as the kernel's REPL does for a v3 VM. A line
|
|
may be 1024 characters, a block. `v4_line_begin`, `v4_line_done` and
|
|
`v4_line_status` (`v4/include/v4/image.h`) are that interface;
|
|
`v4_boot_line` (`v4/system/boot.c`) is the one loop the hosted binary, the
|
|
kernel and the capsule loader all run it with.
|
|
|
|
**This is still the lone node.** On bare metal `kernel_main.c` starts it
|
|
before the fleet tables, beside the kernel's own system and not in the VM's
|
|
place. `ENGINE.md` sets out the steps from here; step 1 is the only one
|
|
done. `V3-PARITY.md` records the rulings it is built from.
|
|
|
|
**What this does not yet show.** `forth79.4th` holds two definitions, `U*`
|
|
and `U/MOD`. Every other word is still in the assembled nucleus, so POST is
|
|
so far a test of the assembled words. Moving them to the capsule, a group at
|
|
a time with POST after each, is the next step (`NUCLEUS.md` section 8).
|
|
|
|
## POST
|
|
|
|
`capsules/v4/post79.4th`: 550 cases in blocks 7000 up, covering 126 of the
|
|
130 words of the FORTH-79 Required Word Set. 443 are v3's cases with what
|
|
the hosted v3 binary did as the expected result. The other 107, and the 27
|
|
v3 cases left out, are listed with reasons in `docs/v4.0.0/POST79.md`.
|
|
|
|
- `make -C v4 post` boots the amd64 system: the quick check after a change.
|
|
- `make -C v4 hosted-check` boots all three hosted ISAs and compares them.
|
|
- `make -C v4 post79` writes the capsule again (`tools/mkpost.py`,
|
|
`tools/post79_rules.py`); it needs the hosted v3 binary.
|
|
|
|
POST is FORTH: a harness of FORTH-79 words and two nucleus hooks, `(CATCH)`
|
|
and `(EMIT-HOOK)`. It forgets itself when it has finished. The boot passes
|
|
only on seeing POST's tally line with `fail=0` (`v4/system/boot.c`). A colon
|
|
definition broken on purpose (`U/MOD` without its last `SWAP`) fails five
|
|
cases and the boot stops with `POST: FAILED`.
|
|
|
|
Not tested: `KEY`, `EXPECT`, `QUERY` (the keyboard) and `QUIT` (it returns
|
|
without ` ok`).
|
|
|
|
Open: `PAD 42 OVER !` faults on v4, because `PAD` is a byte address and `!`
|
|
takes a cell address (D-1). FORTH-79 expects it to work. The v3 case for it
|
|
is left out until that is ruled.
|
|
|
|
The Required Word Set list in `tools/mkpost.py` was written from memory of
|
|
the standard and has not been checked against the document.
|