fix(vm): a text run from inside a line no longer takes the line's place -- LOAD and THRU go on with the rest of it

FABRIC-3.md XXXIV.1, traced and fixed.  vm_interpret() copied each text
into the VM's one input buffer and reset the position.  LOAD runs its
block by calling it, so the block replaced the line LOAD was on and
nothing after LOAD or THRU on that line was ever interpreted; the same
for -->, a capsule's EXEC and a message kernel-Hermes delivers.
vm_interpret() now keeps what the outer text had not yet read when it is
called from inside another, and puts it back after, as FORTH-79's LOAD
keeps the input stream it interrupts.  In the kernel's VM and the hosted
one alike.

POST: LOAD.rest_of_line (1 LOAD 0 0 /) and THRU.rest_of_line
(1 2 THRU 0 0 /) failed without the fix (logs/20261014-061222) and pass
with it.  Three-ISA acceptance: logs/20261014-061508 (amd64), -061624
(aarch64), -061837 (riscv64), 1052 tests, none failed, zuse prompt,
hash 0x08873e0f44b7cb2a unchanged.  The hosted binary: 100 LOAD 1 + .
gives 8.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-14 06:19:54 -04:00
co-authored by Claude Opus 5.5
parent 9772ee8b68
commit c15589b39e
12 changed files with 36712 additions and 4 deletions
+15 -2
View File
@@ -5197,6 +5197,19 @@ sequence at all until/unless this is fixed at the source -- the interactive two-
(typed live over the serial socket) sidesteps the bug, it does not fix it. Flagged here as a
real, reproducible defect worth its own fix later, out of scope for this section.
**Fixed 2026-10-14.** The mechanism, traced: `vm_interpret()` (`kernel/src/vm/vm_core.c`, and
the hosted `v3/src/vm.c`) copies each text it runs into the VM's one `input_buffer` and resets
`input_pos`. `LOAD` runs its block by calling it, so the block took the place of the line `LOAD`
was on, and when the block was done the outer loop found nothing left to read. The same held
for every word that runs text from inside a line: `-->`, a capsule's `EXEC`, a message
kernel-Hermes delivers. `vm_interpret()` now keeps what the outer text had not yet read when it
is called from inside another, and puts it back afterwards, as FORTH-79's `LOAD` keeps the
input stream it interrupts. Two POST cases, `LOAD.rest_of_line` (`1 LOAD 0 0 /`) and
`THRU.rest_of_line` (`1 2 THRU 0 0 /`), fail without the fix (`logs/20261014-061222`) and pass
with it; three-ISA acceptance `logs/20261014-061508` (amd64), `-061624` (aarch64), `-061837`
(riscv64): 1052 tests, none failed, hash `0x08873e0f44b7cb2a` unchanged. So a `THRU`-then-call
line now works as one `SK_CMD`; that use itself was not re-run.
### XXXIV.2 -- A cross-session QEMU collision killed the first real relaunch at 0 trials
Once running for real (via the two-line workaround), the campaign was silently killed a fourth
@@ -5476,8 +5489,8 @@ device it was minted on.
### XXXV.7 -- Genuinely open, not decided here
- **Exact v2 decimation factor**, if/when v2 is built at all (§XXXV.4).
- Whether `THRU`'s own line-swallowing defect (§XXXIV.1, still un-root-caused at the C level) gets
fixed before or after this work -- it blocks true single-command `SK_STARTUP_FORTH` autolaunch
- ~~Whether `THRU`'s own line-swallowing defect (§XXXIV.1, still un-root-caused at the C level) gets
fixed before or after this work~~ Fixed 2026-10-14, before it (§XXXIV.1) -- it blocks true single-command `SK_STARTUP_FORTH` autolaunch
of the campaign regardless of persistence format; the two-line interactive workaround still
applies either way.
- Disposal of the two stale partial amd64 runs' data (§XXXIV.5's own still-open item) is unrelated