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>
62 lines
1.9 KiB
C
62 lines
1.9 KiB
C
/* hosted.c -- StarForth v4 as a Linux program: the nucleus image on the
|
|
* golden model, its capsules loaded as the system comes up (v4/include/v4/
|
|
* boot.h, the same boot the bare-metal kernel runs), the console on stdin
|
|
* and stdout.
|
|
*
|
|
* It runs until its input ends. Blocks are kept in memory and are gone
|
|
* when it stops.
|
|
*/
|
|
#include "v4/boot.h"
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#define BLOCKS 64u
|
|
|
|
static v4_node n;
|
|
static v4_exec_state es;
|
|
static v4_heat h;
|
|
static unsigned char disk[BLOCKS * V4_BLOCK_BYTES];
|
|
|
|
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)
|
|
{
|
|
static char line[1026];
|
|
v4_boot boot;
|
|
|
|
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 (;;) {
|
|
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; }
|
|
}
|
|
}
|