- Text after start is refused, as text.c refuses it: before it jumps, the
ROM reads on to the end of the source; blanks, comments and the ends of
blobs may follow, a token is ERR-AFTER (26), "text after start".
- A token too long where a name, a target or a value is wanted is "name
too long", as text.c says: (MISSING) reports "missing" only when no error
came first. `", keeps "missing", which is text.c's word for both.
- text.c's "address out of range" names the address, not the value.
- The system's source files are one list, v4/sys_files.h: boot.c, the
harness and the nucleus test are made from it.
- The ROM's error codes and words are one list, v4/rom_errors.h: boot.c's
messages, host_map.h's ROM_ERR_* and mkmap's ERR-* are made from it.
- node.h says what v4_node_store does with a ROM address (nothing, as for
any address outside RAM, D-14); test_host_rom_range pins it.
ROM: 2095 words, rom_hash 0x06d0dcb7a0cb41a1. dict_hash unchanged,
0xe5a57f3eb72ff94a. make -C v4 test test-32 hosted-check pass. QEMU:
amd64, aarch64, riscv64 to ok>, POST 538/538, POST: PASSED.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The boot left the source's last new line in the console input, and the
first KEY after the boot read it. What the ROM has not read when it
starts the system is taken back (boot.c, rom_harness.h). hosted-check:
KEY after the boot reads the key typed.
- A comment or macro left open at the end of a blob ran on into the next,
and the ROM accepted source text.c refuses. The loader ends each blob
with FS (V4_ROM_BLOB_END) after its new line; the ROM ends a blob there
as text.c ends a file: an open comment or macro is an error, and the word
being assembled ends. test_host_rom_asm: seven blob pairs against text.c.
- store to an address outside RAM faulted the ROM with no message. It is
now refused, as text.c refuses it: ERR-RANGE, "address out of range".
- The kernel build did not regenerate capsules/v4/sys/map-<w>.f18 before
packing the capsule directory; it now does.
ROM: 2084 words, rom_hash 0x4c458c6e48b35456. dict_hash unchanged,
0xe5a57f3eb72ff94a. make -C v4 test test-32 hosted-check pass. QEMU:
amd64, aarch64, riscv64 to ok>, POST 538/538, POST: PASSED.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The host node starts in its ROM (entry 12), and the boot feeds it the
system's source through the console: capsules/v4/sys/map-64.f18, the
fourteen .f18 blobs and end.f18, each found, hash-checked and
signature-checked as any capsule, then EOT. The ROM assembles the system
and starts it at (IDLE); the host reads the image record
(v4_image_from_node) for what only the assembled system knows. A ROM
error is reported with its blob, line and meaning, then PARITY:FAIL.
Deleted: v4/tools/mkimage.c, capsules/v4/nucleus-64.f18, v4/capsule/*.v4,
v4/tools/v4tof18.py. The .f18 files are the source now.
- text.c speaks the rest of the ROM's language (set, here, store, start;
v4_text_value, v4_text_start), so the oracle reads the same source:
test_host_rom_nucleus compares the ROM against text.c on the .f18 files,
word for word, image record included. Host tests load the .f18 files.
- mkmap image writes v4_map_image (the map's description of the system);
hosted and the kernel link the ROM and the map instead of v4_image_64.c.
- Hera (Captain Bob's ruling, option 1): births stream the system the ROM
assembled, as assembled code; hera.4th is unchanged.
test_host_unit's host builds the system with the ROM.
- New parity lines: PARITY:V4_F18 per blob, PARITY:V4_ROM words=2049
rom_hash=0xa6c792b5821010b7 instructions=60725216.
Acceptance: amd64, aarch64, riscv64 boot to ok> with PARITY:V4_POST
tests=538 pass=538 fail=0, POST: PASSED, and PARITY:V4_SYSTEM
word_count=317 dict_hash=0xe5a57f3eb72ff94a on all three -- the same hash
as the prebuilt nucleus gave. make -C v4 test test-32 hosted-check: all
pass. Logs: logs/20261015-141648, -141938, -142350.
Startup cost under QEMU TCG, the ROM's assembly (last V4_F18 line to
V4_ROM): amd64 26.7 s of 132 s to ok>; aarch64 41.0 s of 195 s; riscv64
20.5 s of 101 s. Hosted native: +0.85 s.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
word.f18: (NEXT-TOKEN) reads the console or a macro being expanded; labels,
branches by name (a label of the word, or a word, now or later), the
table of branches waiting, end of word, FOR/NEXT/UNEXT, macros, &NAME,
CONST+N, and (ONE), which dispatches a token. A forward branch to a name
not yet defined waits on a placeholder symbol, filled in by (DEFINE).
dir.f18: constant set here #, ", store, and start, which resolves, clears
the tables the ROM used and runs the word it names. main.f18: the ROM
itself, entry 12; on an error it stops at (ROM-FAILED) with the code and
line in its state, for the loader to report. sym.f18 generalized: any
counted string, placeholders, a hash of only a name's own cells.
test_host_rom_asm.c gives test_text.c's own texts (accepted and refused),
its four real definitions and the ROM's directives to text.c and to the
ROM: the same words, the same errors on the same lines, at both widths.
The ROM is 2036 words.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(OP) (LIT) (BRANCH) (BRANCH>) (RESOLVE) (LABEL), entries 6-11: the code
generator of any language built on the machine (MACHINE.md 2.1). asm.c's
layout rules with text.c's branch placement; 400 random sequences agree
word for word with asm.c at both widths, memory-full and out-of-reach are
refused on both sides, and a ref with no branch is refused, not looped on.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(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>
(NUMBER) ( -- n flag ), entry 2: decimal with a leading -, or hex after $;
1 a number, 0 not one, -1 one that does not fit a cell. Every case is also
given to text.c, the oracle, at both widths.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The ROM's source is F18 code in capsules/v4/rom, assembled off the node by
v4/tools/mkrom.c with the memory map's constants from v4/tools/mkmap.c
(MACHINE.md 2). main.f18 is the entry table payloads call through (2.1);
in.f18 reads the console and splits it into tokens exactly as text.c does,
the token held packed as a counted string. The ROM's state is a reserved
area of the map (host_map.h ROM_*). text.c gains the constant directive,
so the off-node assembler and the ROM speak one language. The map also
names (NUMBER)'s state, for the next task.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>