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
+23
View File
@@ -1184,6 +1184,23 @@ void vm_interpret(VM* vm, const char* input)
VM *prev_attrib_vm = g_log_attrib_vm;
g_log_attrib_vm = vm;
/* A TEXT RUN FROM INSIDE ANOTHER -- LOAD and THRU, -->, a capsule's EXEC,
* a message kernel-Hermes delivers -- takes the VM's one input buffer.
* What the outer text had not yet read is kept here and put back, so
* that it goes on after: FORTH-79's LOAD keeps the input stream it
* interrupts. Before 2026-10-14 it was overwritten, and everything
* after `5044 5055 THRU` on a line was never interpreted
* (FABRIC-3.md XXXIV.1). */
int nested = g_vm_interpret_depth > 0;
char outer_buffer[INPUT_BUFFER_SIZE];
size_t outer_length = 0, outer_pos = 0;
if (nested) {
size_t k;
outer_length = vm->input_length < INPUT_BUFFER_SIZE ? vm->input_length : INPUT_BUFFER_SIZE - 1;
outer_pos = vm->input_pos;
for (k = 0; k < outer_length; k++) outer_buffer[k] = vm->input_buffer[k];
outer_buffer[outer_length] = '\0';
}
g_vm_interpret_depth++;
/* Load into input buffer (cap + NUL) */
@@ -1218,6 +1235,12 @@ void vm_interpret(VM* vm, const char* input)
}
g_vm_interpret_depth--;
if (nested) {
size_t k;
for (k = 0; k <= outer_length; k++) vm->input_buffer[k] = outer_buffer[k];
vm->input_length = outer_length;
vm->input_pos = outer_pos;
}
g_log_attrib_vm = prev_attrib_vm;
}