feat(v4.0.0): a node is handed a line -- ENGINE.md step 1
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>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
ab7a9bf06f
commit
01c447f9ab
+30
-17
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
#include "v4/boot.h"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#define BLOCKS 64u
|
||||
|
||||
@@ -22,27 +22,40 @@ static void console_out(const char *text, unsigned len)
|
||||
(void)fwrite(text, 1, len, stdout);
|
||||
}
|
||||
|
||||
/* a character for a line that reads the keyboard */
|
||||
static int console_key(void)
|
||||
{
|
||||
int c;
|
||||
fflush(stdout);
|
||||
c = getchar();
|
||||
return c == EOF ? V4_BOOT_KEY_END : c;
|
||||
}
|
||||
|
||||
/* The prompt is the host's, as it is the kernel's REPL's for a v3 VM: read a
|
||||
* line, hand it to the node, say how it ended. */
|
||||
int main(void)
|
||||
{
|
||||
const v4_image *im = &v4_capsule_image;
|
||||
unsigned char buf[256];
|
||||
static char line[1026];
|
||||
v4_boot boot;
|
||||
|
||||
boot.n = &n; boot.es = &es; boot.h = &h; boot.im = im; boot.out = console_out;
|
||||
boot.n = &n; boot.es = &es; boot.h = &h; boot.im = &v4_capsule_image;
|
||||
boot.out = console_out; boot.key = console_key;
|
||||
if (!v4_boot_run(&boot, disk, BLOCKS)) { fflush(stdout); return 1; }
|
||||
|
||||
for (;;) {
|
||||
(void)v4_exec_step_word(&n, &es, &h);
|
||||
if (n.console_len) {
|
||||
(void)fwrite(n.console, 1, n.console_len, stdout);
|
||||
n.console_len = 0;
|
||||
}
|
||||
if (n.stopped) { fflush(stdout); fprintf(stderr, "starforth4: the node stopped on a fault\n"); return 1; }
|
||||
if (v4_image_waiting(&n, im)) {
|
||||
ssize_t got;
|
||||
fflush(stdout);
|
||||
got = read(0, buf, sizeof buf);
|
||||
if (got <= 0) { putchar('\n'); return 0; }
|
||||
(void)v4_node_console_feed(&n, buf, (unsigned)got);
|
||||
}
|
||||
size_t len;
|
||||
int how;
|
||||
|
||||
fputs("ok> ", stdout);
|
||||
fflush(stdout);
|
||||
if (!fgets(line, sizeof line, stdin)) { putchar('\n'); return 0; }
|
||||
len = strlen(line);
|
||||
if (len && line[len - 1] == '\n') len--;
|
||||
how = v4_boot_line(&boot, line, (unsigned)len);
|
||||
if (how == V4_LINE_COMPLETED) fputs(" ok\n", stdout);
|
||||
else if (how == V4_LINE_ERROR) fputs(" ERROR\n", stdout);
|
||||
else if (how == V4_BOOT_LINE_TOO_LONG) fputs("Line too long\n ERROR\n", stdout);
|
||||
else if (how == V4_BOOT_LINE_NO_INPUT) { putchar('\n'); return 0; }
|
||||
else if (how == V4_BOOT_LINE_STOPPED) { fflush(stdout); fprintf(stderr, "starforth4: the node stopped on a fault\n"); return 1; }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user