/* 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 #include #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 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) { 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; 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 (;;) { 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_TEXT_COMPLETED) fputs(" ok\n", stdout); if (leaving) { fflush(stdout); return 0; } else if (how == V4_TEXT_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; } } }