143 lines
4.9 KiB
C
143 lines
4.9 KiB
C
/*
|
||
StarForth — Steady-State Virtual Machine Runtime
|
||
|
||
Copyright (c) 2023–2025 Robert A. James
|
||
All rights reserved.
|
||
|
||
Licensed under the StarForth License, Version 1.0
|
||
*/
|
||
|
||
/**
|
||
* repl.h - Emergency FORTH REPL for LithosAnanke kernel
|
||
*/
|
||
|
||
#ifndef STARKERNEL_REPL_H
|
||
#define STARKERNEL_REPL_H
|
||
|
||
#include "vm.h"
|
||
#include "starkernel/homeblocks_sig.h"
|
||
|
||
struct blkio_dev;
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
/**
|
||
* sk_repl - Run the emergency FORTH REPL on the serial console.
|
||
*
|
||
* Blocks until vm->halted is set (BYE word) or the VM encounters a halt.
|
||
* Runs with interrupts enabled; the APIC heartbeat continues to fire.
|
||
*
|
||
* @param vm Mama VM instance (must be fully initialised)
|
||
*/
|
||
void sk_repl(VM *vm);
|
||
|
||
/**
|
||
* sk_repl_run - Bare REPL loop (no banner).
|
||
*
|
||
* Same as sk_repl but skips the version/welcome banner. Used by START
|
||
* to enter a child VM's interpreter loop without reprinting the header.
|
||
*
|
||
* @param vm Fully initialised VM instance
|
||
*/
|
||
void sk_repl_run(VM *vm);
|
||
|
||
/**
|
||
* sk_repl_step - Execute one REPL turn on a VM and return.
|
||
*
|
||
* Prints the VM's prompt, reads one line, interprets it, prints ok/ERROR,
|
||
* then returns. Used by the Compudynamics VM-STEP primitive so Hera can
|
||
* give a single REPL quantum to a child VM without surrendering control
|
||
* for the full sk_repl_run() loop.
|
||
*
|
||
* @param vm Fully initialised VM instance
|
||
* @return 1 if the VM is still running, 0 if it halted during this turn
|
||
*/
|
||
int sk_repl_step(VM *vm);
|
||
|
||
/**
|
||
* sk_repl_set_active_vm - Redirect REPL input to a different VM (USE word).
|
||
*
|
||
* Pass NULL to restore default dispatch (Mama's VM).
|
||
* The change takes effect on the next REPL iteration.
|
||
*
|
||
* @param vm Target VM, or NULL for default
|
||
*/
|
||
void sk_repl_set_active_vm(VM *vm);
|
||
|
||
/**
|
||
* sk_repl_get_active_vm - Return the current USE-redirected VM, or NULL.
|
||
*/
|
||
VM *sk_repl_get_active_vm(void);
|
||
|
||
/**
|
||
* sk_repl_get_homeblocks_dev / sk_repl_get_homeblocks_sig - The currently
|
||
* attached home-blocks USB drive, or NULL if none is attached / the
|
||
* attached drive didn't check out as HOMEBLOCKS_SIG_OK (FABRIC-3.md
|
||
* §F.6/§F.9/§F.18). Both return NULL together; never one without the
|
||
* other.
|
||
*/
|
||
struct blkio_dev *sk_repl_get_homeblocks_dev(void);
|
||
const homeblocks_sig_t *sk_repl_get_homeblocks_sig(void);
|
||
|
||
/**
|
||
* sk_repl_get_attached_blk_dev - The currently attached USB block
|
||
* device, regardless of home-blocks recognition (FABRIC-3.md
|
||
* §F.8/§F.19) -- MINT's own target, since a blank/unminted drive never
|
||
* sets sk_repl_get_homeblocks_dev() above. NULL if nothing is attached.
|
||
*/
|
||
struct blkio_dev *sk_repl_get_attached_blk_dev(void);
|
||
|
||
/**
|
||
* sk_console_getkey - Real body of the standard dictionary's KEY word
|
||
* (called from shim.c's getchar()). Blocks until a key is available from
|
||
* either input source (serial console or the PS2/virtio keyboard-event
|
||
* bridge), servicing the heartbeat/idle loop while waiting so a KEY call
|
||
* from inside any word never stalls the heartbeat. No echo -- that's the
|
||
* caller's responsibility, same as any standard KEY.
|
||
*
|
||
* @param active_vm VM whose idle dispatch runs while waiting (see
|
||
* sk_repl_idle()'s own doc comment on why this is a
|
||
* parameter rather than read via sk_repl_get_active_vm())
|
||
* @return the key read, as an unsigned byte value
|
||
*/
|
||
int sk_console_getkey(VM *active_vm);
|
||
|
||
/**
|
||
* sk_console_key_available - Real body of the standard dictionary's
|
||
* ?TERMINAL word (called from sf_terminal_ready()). Non-blocking peek:
|
||
* returns 1 if a key is ready without consuming it (a following
|
||
* sk_console_getkey() returns that exact key), 0 otherwise.
|
||
*/
|
||
int sk_console_key_available(void);
|
||
|
||
/**
|
||
* sk_console_readline - Real body of the standard dictionary's
|
||
* QUERY/EXPECT words (called from shim.c's fgets()). Reads one line from
|
||
* the console with echo and backspace support, servicing the heartbeat/
|
||
* idle loop while waiting -- the same line editor the REPL's own prompt
|
||
* uses internally, so a mid-word EXPECT behaves identically to typing at
|
||
* "ok>" itself.
|
||
*
|
||
* @param buf Destination buffer
|
||
* @param size Buffer capacity, including the NUL terminator
|
||
* @param active_vm VM whose idle dispatch runs while waiting
|
||
* @param reanchor_prompt Nonzero to re-print the "ok> " prompt whenever
|
||
* an idle bottom half (heartbeat, USB attach/detach) writes
|
||
* to the console while this readline blocks at a bare,
|
||
* untyped prompt -- keeps the top-level prompt as the last
|
||
* thing shown once the chatter dies down. Callers whose
|
||
* prompt line is their own (shim.c's fgets(), i.e.
|
||
* QUERY/EXPECT/ACCEPT) pass 0 so "ok> " never gets stamped
|
||
* onto their mid-word input context.
|
||
* @return number of characters placed in buf, not counting the NUL
|
||
*/
|
||
int sk_console_readline(char* buf, int size, VM* active_vm, int reanchor_prompt);
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
|
||
#endif /* STARKERNEL_REPL_H */
|