feat(v4.0.0): a node asks its kernel by a blocking write to its port
ENGINE.md step 2, the carrier. Ruled 2026-10-05 (V3-PARITY.md 1i), on DECOMPOSITION.md section 6: a write to a port blocks until the neighbour reads. - node: v4_node_port_attach, v4_node_port_served; a store to the port keeps the value as the request and blocks the node - exec: a blocked node executes nothing; served, it goes on from the opcode after the store, in the same instruction word; a fault meanwhile abandons the rest of the word - compile.v4: n KERNEL-WORD name makes a word whose body writes n to the port; its arguments and results are on the data stack - boot: the kernel's words are made by handing the node text, and requests are served between the node's opcodes; one no one serves is error 12 - BYE, the first kernel word: hosted it leaves the program, as hosted v3; on the lone node it is v3's cold restart - ENGINE.md 3a: multiuser, multitasking, preemptive and cooperative, and what that asks of the engine Verified: make -C v4 test passes at both widths, with tests/test_port.c; hosted-check passes on three ISAs; clean qemu with STARFORTH_V4=1 on amd64, aarch64 and riscv64 passes POST with the same hashes as hosted, and a kernel word no one serves and BYE typed at each prompt are answered (logs/20261005-185506, -185734, -190101; -185234 is an amd64 run in which those two lines were not typed). Not done: v3's own C functions serving a node. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
5f1f60fc84
commit
8df6c16766
@@ -31,6 +31,20 @@ static int console_key(void)
|
||||
return c == EOF ? V4_BOOT_KEY_END : c;
|
||||
}
|
||||
|
||||
/* THE KERNEL'S WORDS, for a node that is a Linux program: the words that
|
||||
* are C in hosted v3 because only the host can do them. */
|
||||
static const char *const kernel_words[] = { "BYE" };
|
||||
static int leaving;
|
||||
|
||||
static void serve(v4_node *node, unsigned request)
|
||||
{
|
||||
(void)node;
|
||||
if (request == 1) { /* BYE ( -- ): as hosted v3, say so and leave */
|
||||
fputs("Goodbye!\n", stdout);
|
||||
leaving = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
@@ -40,6 +54,7 @@ int main(void)
|
||||
|
||||
boot.n = &n; boot.es = &es; boot.h = &h; boot.im = &v4_capsule_image;
|
||||
boot.out = console_out; boot.key = console_key;
|
||||
boot.words = kernel_words; boot.word_count = sizeof kernel_words / sizeof kernel_words[0]; boot.serve = serve;
|
||||
if (!v4_boot_run(&boot, disk, BLOCKS)) { fflush(stdout); return 1; }
|
||||
|
||||
for (;;) {
|
||||
@@ -53,6 +68,7 @@ int main(void)
|
||||
if (len && line[len - 1] == '\n') len--;
|
||||
how = v4_boot_line(&boot, line, (unsigned)len);
|
||||
if (how == V4_LINE_COMPLETED) fputs(" ok\n", stdout);
|
||||
if (leaving) { fflush(stdout); return 0; }
|
||||
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; }
|
||||
|
||||
+2
-2
@@ -100,8 +100,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
fprintf(out, "};\n\nconst v4_image v4_capsule_image = {\n cells, %uu,\n %uu, %uu, %uu, %uu,\n", count,
|
||||
(unsigned)V4_CELL_BITS, (unsigned)V4_NODE_WORDS, (unsigned)V4_DATA_RING, (unsigned)V4_RET_RING);
|
||||
fprintf(out, " %ld, %ld, %ld,\n %ld, %uu, %ld,\n %ld,\n %ld, %ld,\n", (long)line, (long)idle, (long)LINE_STATUS,
|
||||
(long)TIB, 1025u, (long)SPAN, (long)faults, (long)w_key, (long)w_key_end);
|
||||
fprintf(out, " %ld, %ld, %ld,\n %ld, %uu, %ld,\n %ld, %ld,\n %ld, %ld,\n", (long)line, (long)idle, (long)LINE_STATUS,
|
||||
(long)TIB, 1025u, (long)SPAN, (long)faults, (long)PORT, (long)w_key, (long)w_key_end);
|
||||
fprintf(out, " %ld, %ld, %ld,\n %ld, %ld,\n %ld,\n %ld,\n %ld, %ld\n};\n", (long)CONSOLE_TX, (long)CONSOLE_RX, (long)CONSOLE_ST,
|
||||
(long)DSTACK_REG, (long)RSTACK_REG, (long)NODE_ERROR, (long)STORAGE_REG, (long)DP, (long)LATEST);
|
||||
if (fclose(out) != 0) die("cannot write", argv[1]);
|
||||
|
||||
Reference in New Issue
Block a user