Lists every C-registered StarForth primitive with stack notation and usage notes, grouped by module, plus a section on implementation quirks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BY9HMwK5Cetz3caBgHGyds
55 KiB
StarForth Primitive Word Reference
This reference covers every C-implemented primitive word that StarForth registers. It was built from
admin/LithosAnanake at commit 6302dcb (2026-09-23). It lists only words registered in C
through register_word() or vm_create_word(). Words defined in FORTH inside capsules (*.4th) are out of scope.
Sources:
src/word_registry.c:register_forth79_words()registers the core set in every VM.src/word_source/*.c: one file per module.src/starkernel/capsule/mama_forth_words.c: kernel-only Hera (Mama) and child-VM words.src/starkernel/repl.candsrc/starkernel/doe_log.c: kernel-only REPL and DoE words.
Conventions
| Item | Meaning |
|---|---|
| Cell | cell_t is int64_t, so every cell is 64 bits and signed. |
| Flag | TRUE is -1 (all bits set) and FALSE is 0. Words that take a flag treat any non-zero value as true. |
addr |
A VM address: a byte offset into the VM's 5 MB linear memory (VM_MEMORY_SIZE), not a host pointer. |
c-addr u |
A string given as its address and length. |
d, ud |
A double-cell number made of two cells, with the high cell on top. |
xt |
An execution token. In StarForth this is the DictEntry* of the word. |
q |
A Q48.16 fixed-point value in one cell (1.0 = 65536). |
"name" |
The word parses a name from the input stream after it. |
( R: ... ) |
The effect on the return stack. |
| IMM | The word is IMMEDIATE, so it runs even while compiling. |
| CO | The word is compile-only and sets vm->error if used outside a definition. |
| K | The word is registered only in the kernel build (__STARKERNEL__). |
| H | The word is registered only in the hosted build (the Linux or macOS binary). |
Errors: a primitive does not throw. On stack underflow or overflow, a bad address, or division by zero it sets
vm->error = 1 and logs a message.
Stack limits: the data stack and return stack hold 1024 cells each (STACK_SIZE). A word name can be at most 31
characters (WORD_NAME_MAX).
Shadowing: when a later module registers a name again, the newer entry wins lookups. For example, MOD, /MOD,
*/ and */MOD are registered by the arithmetic module and again by the mixed-arithmetic module, so the
mixed-arithmetic versions are the active ones.
Contents
- Stack
- Return stack
- Memory
- Arithmetic
- Logic and comparison
- Mixed-precision arithmetic
- Double-cell numbers
- Number formatting and output
- Strings, parsing, and input
- Terminal I/O
- Blocks and mass storage
- Dictionary space
- Dictionary manipulation
- Vocabularies
- System
- Line editor
- Defining words and the compiler
- Control flow
- StarForth extensions
- Word-level ACL
- Physics: benchmark and diagnostics
- Physics: pipelining diagnostics
- Physics: freeze, heat, and decay
- Dictionary heat optimisation
- Logging
- Q48.16 fixed-point math
- Inference engine (SSM, L8, and Bayes)
- DEFER and IS
- Framebuffer (Hestia only)
- Keyboard
- TrueType text
- REPL scrollback
- Kernel REPL and DoE hooks
- Hera (Mama) and child-VM words
- Hosted lifecycle stubs
- Implementation quirks to know
1. Stack
src/word_source/stack_words.c
| Word | Stack | Description |
|---|---|---|
DROP |
( x -- ) |
Discards the top cell. |
DUP |
( x -- x x ) |
Copies the top cell. |
?DUP |
( x -- x x | 0 -- 0 ) |
Copies the top cell only when it is non-zero. The usual idiom is ?DUP IF ... THEN. |
SWAP |
( x1 x2 -- x2 x1 ) |
Swaps the top two cells. |
OVER |
( x1 x2 -- x1 x2 x1 ) |
Copies the second cell to the top. |
ROT |
( x1 x2 x3 -- x2 x3 x1 ) |
Moves the third cell to the top. |
-ROT |
( x1 x2 x3 -- x3 x1 x2 ) |
Moves the top cell down to third place. This is the reverse of ROT. |
DEPTH |
( -- n ) |
Pushes the number of cells that were on the data stack before DEPTH ran. |
PICK |
( xn … x0 n -- xn … x0 xn ) |
Copies the n-th cell to the top. 0-based: 0 PICK is DUP and 1 PICK is OVER. An error occurs if n < 0 or n ≥ depth. |
ROLL |
( … n -- … ) |
Moves a cell to the top and closes the gap. Non-standard: n counts from the bottom of the stack (1-based), so 1 ROLL moves the deepest cell to the top. 0 ROLL does nothing. See §36. |
2. Return stack
src/word_source/return_stack_words.c
| Word | Stack | Description |
|---|---|---|
>R |
( x -- ) ( R: -- x ) |
Moves a cell from the data stack to the return stack. Inside a definition, balance it with R> before ; or EXIT. |
R> |
( -- x ) ( R: x -- ) |
Moves a cell from the return stack back to the data stack. |
R@ |
( -- x ) ( R: x -- x ) |
Copies the top of the return stack without removing it. |
3. Memory
src/word_source/memory_words.c. Every address is a VM byte offset and is checked against the VM's memory bounds.
| Word | Stack | Description |
|---|---|---|
@ |
( addr -- x ) |
Fetches the cell at addr. |
! |
( x addr -- ) |
Stores x at addr. |
C@ |
( addr -- c ) |
Fetches the byte at addr, zero-extended. |
C! |
( c addr -- ) |
Stores the low 8 bits of c at addr. |
+! |
( n addr -- ) |
Adds n to the cell at addr. |
-! |
( n addr -- ) |
Subtracts n from the cell at addr. |
2@ |
( addr -- x-lo x-hi ) |
Fetches two cells: the low cell from addr and the high cell from addr+8, leaving the high cell on top. |
2! |
( x-lo x-hi addr -- ) |
Stores two cells: the low cell at addr and the high cell at addr+8. |
FILL |
( addr u c -- ) |
Fills u bytes starting at addr with the byte c. |
MOVE |
( src dst u -- ) |
Copies u bytes from src to dst. It is safe when the ranges overlap because it uses memmove semantics. |
ERASE |
( addr u -- ) |
Sets u bytes to zero. |
CELLS |
( n -- n*8 ) |
Scales a cell count to a byte count. |
4. Arithmetic
src/word_source/arithmetic_words.c. All arithmetic is signed 64-bit, and division truncates toward zero as in C.
| Word | Stack | Description |
|---|---|---|
+ |
( n1 n2 -- n1+n2 ) |
Adds the two cells. |
- |
( n1 n2 -- n1-n2 ) |
Subtracts n2 from n1. |
* |
( n1 n2 -- n1*n2 ) |
Multiplies the two cells. The result wraps modulo 2⁶⁴. |
/ |
( n1 n2 -- n1/n2 ) |
Divides, truncating toward zero. Division by zero sets an error. |
MOD |
( n1 n2 -- rem ) |
Pushes the remainder of n1 / n2, which has the sign of n1. This name is shadowed by §6. |
/MOD |
( n1 n2 -- rem quot ) |
Pushes the remainder and the quotient, with the quotient on top. This name is shadowed by §6. |
*/ |
( n1 n2 n3 -- n1*n2/n3 ) |
Multiplies and then divides using a wide intermediate. This name is shadowed by §6. |
*/MOD |
( n1 n2 n3 -- rem quot ) |
Like */, but also leaves the remainder. This name is shadowed by §6. |
1+ 1- |
( n -- n±1 ) |
Increments or decrements by 1. |
2+ 2- |
( n -- n±2 ) |
Adds or subtracts 2. |
2* |
( n -- n*2 ) |
Shifts left by one bit. |
2/ |
( n -- n/2 ) |
Shifts right by one bit, keeping the sign (arithmetic shift). |
ABS |
( n -- |n| ) |
Pushes the absolute value. |
NEGATE |
( n -- -n ) |
Pushes the two's-complement negation. |
MIN MAX |
( n1 n2 -- n3 ) |
Pushes the smaller or the larger value, compared as signed numbers. |
5. Logic and comparison
src/word_source/logical_words.c. Comparison words return a proper flag of -1 or 0.
| Word | Stack | Description |
|---|---|---|
AND OR XOR |
( x1 x2 -- x3 ) |
Bitwise AND, OR, and XOR. |
NOT |
( x -- flag ) |
FORTH-79 logical NOT: 0 gives TRUE and any other value gives FALSE. This is not a bitwise complement; use INVERT for that. |
INVERT |
( x -- ~x ) |
Bitwise complement (from FORTH-83). |
LSHIFT |
( x u -- x<<u ) |
Logical shift left by u bits. |
RSHIFT |
( x u -- x>>u ) |
Logical (unsigned) shift right by u bits. |
0= |
( n -- flag ) |
True if n is 0. |
0< |
( n -- flag ) |
True if n is negative. |
0> |
( n -- flag ) |
True if n is positive. |
0<> |
( n -- flag ) |
True if n is not 0. |
= <> |
( n1 n2 -- flag ) |
Tests for equality or inequality. |
< > <= >= |
( n1 n2 -- flag ) |
Signed comparisons of n1 against n2. |
U< U> |
( u1 u2 -- flag ) |
Unsigned comparisons. |
WITHIN |
( n lo hi -- flag ) |
True if lo ≤ n < hi, using the standard half-open range. |
TRUE |
( -- -1 ) |
Pushes the canonical true flag. |
FALSE |
( -- 0 ) |
Pushes the canonical false flag. |
6. Mixed-precision arithmetic
src/word_source/mixed_arithmetic_words.c. A double here means two full 64-bit cells (128 bits).
| Word | Stack | Description |
|---|---|---|
M+ |
( d n -- d' ) |
Adds a signed single to a double and propagates the carry into the high cell. |
M- |
( d n -- d' ) |
Subtracts a signed single from a double and propagates the borrow. |
M* |
( n1 n2 -- d ) |
Multiplies 64×64 into a full 128-bit signed product, using __int128 internally. The result can be printed with D.. |
M/MOD |
( d n -- rem quot ) |
Divides a 128-bit double by a single, leaving the quotient on top. It uses bit-serial long division, so it works in the freestanding kernel without libgcc. |
MOD |
( n1 n2 -- rem ) |
Active version. Computes n1 % n2. Division by zero sets an error. |
/MOD |
( n1 n2 -- rem quot ) |
Active version. Leaves the remainder under the quotient. Division by zero sets an error. |
*/ |
( n1 n2 n3 -- n4 ) |
Active version. Computes (n1*n2)/n3 with a wide intermediate, so n1*n2 does not overflow. Division by zero sets an error. Typical use is scaling, for example x 355 113 */. |
*/MOD |
( n1 n2 n3 -- rem quot ) |
Active version. Like */, but also leaves the remainder under the quotient. |
7. Double-cell numbers
src/word_source/double_words.c. In every stack picture, d stands for the pair ( lo hi ) with the high cell on top.
| Word | Stack | Description |
|---|---|---|
S>D |
( n -- d ) |
Sign-extends a single to a double. |
D+ D- |
( d1 d2 -- d3 ) |
Double add and subtract, with carry or borrow. |
DNEGATE |
( d -- -d ) |
Negates a double. |
DABS |
( d -- |d| ) |
Pushes the absolute value of a double. |
DMAX DMIN |
( d1 d2 -- d3 ) |
Pushes the larger or smaller double, compared as signed values. |
D< |
( d1 d2 -- flag ) |
Signed less-than on doubles. |
D= |
( d1 d2 -- flag ) |
Equality on doubles. |
D0= |
( d -- flag ) |
True if the double is zero. |
D0< |
( d -- flag ) |
True if the double is negative. |
D2* |
( d -- d*2 ) |
Shifts a double left by one bit across both cells. |
D2/ |
( d -- d/2 ) |
Shifts a double right by one bit (arithmetic shift) across both cells. |
2DROP |
( x1 x2 -- ) |
Drops a cell pair. |
2DUP |
( x1 x2 -- x1 x2 x1 x2 ) |
Duplicates a cell pair. |
2SWAP |
( p1 p2 -- p2 p1 ) |
Swaps two cell pairs. |
2OVER |
( p1 p2 -- p1 p2 p1 ) |
Copies the second pair to the top. |
2ROT |
( p1 p2 p3 -- p2 p3 p1 ) |
Rotates three cell pairs. |
2>R |
( x1 x2 -- ) ( R: -- x1 x2 ) |
Moves a pair to the return stack. |
2R> |
( -- x1 x2 ) ( R: x1 x2 -- ) |
Moves a pair back from the return stack. |
2R@ |
( -- x1 x2 ) ( R: x1 x2 -- x1 x2 ) |
Copies a pair from the return stack. |
8. Number formatting and output
src/word_source/format_words.c
| Word | Stack | Description |
|---|---|---|
. |
( n -- ) |
Prints a signed number in the current BASE, followed by a space. |
.R |
( n width -- ) |
Prints a signed number right-aligned in a field width characters wide. |
U. |
( u -- ) |
Prints an unsigned number followed by a space. |
U.R |
( u width -- ) |
Prints an unsigned number right-aligned. |
D. |
( d -- ) |
Prints a signed double. |
D.R |
( d width -- ) |
Prints a signed double right-aligned. |
.S |
( -- ) |
Prints the data stack without changing it. This is the main debugging aid. |
? |
( addr -- ) |
Prints the cell at addr; it is the same as @ .. |
DUMP |
( addr u -- ) |
Prints a hex and ASCII dump of u bytes starting at addr. |
<# |
( -- ) |
Starts pictured numeric output by resetting the conversion buffer. |
# |
( ud -- ud' ) |
Converts one digit (ud mod BASE) into the buffer. It also accepts a single signed cell and converts its magnitude. |
#S |
( ud -- 0 0 ) |
Converts digits until the value is zero, always producing at least one digit. It accepts a single cell the same way # does. |
HOLD |
( c -- ) |
Inserts the character c into the pictured output buffer. |
SIGN |
( n -- ) |
Inserts - if n is negative. |
#> |
( ud -- c-addr u ) |
Ends conversion and leaves the string. It is tolerant: it pops ud only if one is present. |
BASE |
( -- addr ) |
Pushes the address of the number-conversion radix variable. |
DECIMAL HEX OCTAL |
( -- ) |
Sets BASE to 10, 16, or 8. |
Example: : .$ ( n -- ) <# # # 46 HOLD #S #> TYPE ; prints 1234 as 12.34.
9. Strings, parsing, and input
src/word_source/string_words.c. The comparison and search words below also accept a counted string in place of an
addr u pair; they detect it when the first byte at addr equals u.
| Word | Stack | Description |
|---|---|---|
COUNT |
( c-addr1 -- c-addr2 u ) |
Converts a counted string (length byte followed by characters) into an address and length. |
EXPECT |
( addr u -- ) |
Reads up to u characters from the terminal into addr and stores the count read in SPAN. |
SPAN |
( -- addr ) |
Pushes the address of the variable that holds the count from the last EXPECT. |
QUERY |
( -- ) |
Reads a line into TIB and resets >IN. |
TIB |
( -- addr ) |
Pushes the address of the terminal input buffer. |
>IN |
( -- addr ) |
Pushes the address of the offset into the current input source. |
SOURCE |
( -- addr u ) |
Pushes the current input buffer and its length. |
WORD |
( c -- c-addr ) |
Skips leading c characters, parses up to the next c, and returns a counted string. The usual form is BL WORD. |
BL |
( -- 32 ) |
Pushes the ASCII space character. |
S" IMM |
( "ccc<">" -- c-addr u ) |
In interpret mode, stores the string at HERE and pushes it. When compiling, it compiles (s") followed by the inline text. |
(s") |
( -- c-addr u ) |
Runtime for a compiled S": reads the inline [len][chars][pad] block and skips the IP past it. The compiler inserts it; you do not call it directly. |
['] IMM |
( "name" -- xt ) |
While compiling, compiles the xt of name as a literal. In interpret mode it behaves like '. |
LITERAL [LITERAL] |
– | Placeholders that do nothing. LITERAL is re-registered in §17 (the working version); [LITERAL] has no replacement and still does nothing. |
CONVERT |
( d1 addr1 -- d2 addr2 ) |
Accumulates the digits at addr1+1… into d1 and stops at the first non-digit. This is a simplified version. |
NUMBER |
( c-addr -- n flag ) |
Converts a counted string to a number. Only base 10 is supported, and flag shows whether it succeeded. |
ENCLOSE |
( addr c -- addr n1 n2 n3 ) |
The classic FIG parser: gives the offsets of the start of the token, the delimiter after it, and the next character. |
-TRAILING |
( addr u -- addr u' ) |
Removes trailing spaces from the length. |
CMOVE |
( src dst u -- ) |
Copies bytes upward from low to high addresses. It is safe for overlapping ranges when dst ≤ src. |
CMOVE> |
( src dst u -- ) |
Copies bytes downward from high to low addresses. It is safe for overlapping ranges when dst > src. |
COMPARE |
( a1 u1 a2 u2 -- n ) |
Compares two strings case-sensitively and returns -1, 0, or 1. |
SEARCH |
( a1 u1 a2 u2 -- a3 u3 flag ) |
Finds string 2 inside string 1. If found, it returns the tail starting at the match and -1. If not, it returns string 1 unchanged and 0. |
SCAN |
( addr u c -- addr' u' ) |
Advances to the first occurrence of c. If there is none, it returns the end of the string and 0. |
SKIP |
( addr u c -- addr' u' ) |
Skips leading occurrences of c. |
BLANK |
( addr u -- ) |
Fills u bytes with spaces. |
10. Terminal I/O
src/word_source/io_words.c
| Word | Stack | Description |
|---|---|---|
EMIT |
( c -- ) |
Prints one character. |
CR |
( -- ) |
Prints a newline. |
KEY |
( -- c ) |
Waits for a character and pushes it. |
?TERMINAL |
( -- flag ) |
True if a key is waiting. It does not block. |
TYPE |
( c-addr u -- ) |
Prints u characters. |
SPACE |
( -- ) |
Prints one space. |
SPACES |
( n -- ) |
Prints n spaces. |
." IMM |
( "ccc<">" -- ) |
In interpret mode, prints the string immediately. When compiling, it compiles (do-string) and the inline text. |
(do-string) |
( -- ) |
Runtime for a compiled .": prints the inline string and skips the IP past it. The compiler inserts it; you do not call it directly. |
11. Blocks and mass storage
src/word_source/block_words.c. A block is 1024 bytes, viewed as 16 lines of 64 characters. Block numbers are
LBNs (logical block numbers) in one address space that spans every attached device.
| Word | Stack | Description |
|---|---|---|
BLOCK |
( u -- addr ) |
Returns the VM address of the buffer holding block u, reading it from disk if needed. It does not mark the buffer dirty. |
BUFFER |
( u -- addr ) |
Assigns a buffer to block u without reading from disk and marks it dirty. Use it when you will overwrite the whole block. |
UPDATE |
( -- ) |
Marks the current (SCR) block dirty and syncs it to the C block layer. |
SAVE-BUFFERS |
( -- ) |
Writes every dirty buffer to disk. |
EMPTY-BUFFERS |
( -- ) |
Discards every buffer without writing it and zeroes the user block window. |
FLUSH |
( -- ) |
Runs SAVE-BUFFERS and then invalidates all buffers. |
LOAD |
( u -- ) |
Sets SCR to u and interprets the 1024 bytes of block u as FORTH source. Block 0 cannot be loaded. |
THRU |
( u1 u2 -- ) |
Loads blocks u1 through u2, including both ends. |
--> |
( -- ) |
Inside a block being loaded, continues interpreting at the next block. |
LIST |
( u -- ) |
Sets SCR to u and prints the block. |
SCR |
( -- addr ) |
Pushes the address of the variable holding the block number last listed or loaded. |
BLK-CONFIRM-FORMAT |
( lbn -- ) |
Commits the container format of the device that owns lbn. Until this has run, the block layer refuses every write to that device. Only the owner (for example Artemis) should call it, and only after checking the disk contents are safe to touch. |
RELOCATE-BLOCK |
( home target -- ) |
Moves the contents of home to target and redirects all later access to home through target. It is a mechanical primitive: it does not check whether target is free or owned by the caller. |
BLK-ACL-ALLOW@ |
( blk -- allow ) |
Reads the cached allow/deny flag of a block's ACL. |
BLK-ACL-ALLOW! |
( allow blk -- ) |
Sets a block's cached allow/deny flag. |
BLK-ACL-TTL@ |
( blk -- ttl ) |
Reads a block's ACL TTL countdown. |
BLK-ACL-TTL! |
( ttl blk -- ) |
Sets a block's ACL TTL countdown. |
BLK-OWNER@ |
( blk -- fp ) |
Pushes the 8-byte owner fingerprint as the raw bits of one cell. There is no BLK-OWNER!: ownership is set only in C, during MINT or birth. |
BLK-ATTACH |
( dev-ptr -- ok? ) |
Registers an already-open blkio_dev_t*, passed as a raw pointer cell, in the unified LBN space. The pointer is trusted without checks. Artemis's USB-attach handler uses it. |
12. Dictionary space
src/word_source/dictionary_words.c
| Word | Stack | Description |
|---|---|---|
HERE |
( -- addr ) |
Pushes the next free byte in the dictionary. |
ALIGN |
( -- ) |
Rounds HERE up to the next 8-byte cell boundary. |
ALLOT |
( n -- ) |
Reserves n bytes at HERE. A negative n gives space back. |
, |
( x -- ) |
Compiles one cell at HERE and advances HERE. |
C, |
( c -- ) |
Compiles one byte. |
2, |
( x-lo x-hi -- ) |
Compiles two cells, low cell first. |
PAD |
( -- addr ) |
Pushes the address of a 512-byte scratch buffer near the top of memory. It is safe for temporary strings. |
SP@ |
( -- n ) |
Pushes the data stack pointer index (dsp). An empty stack gives -1 and one item gives 0. |
SP! |
( n -- ) |
Restores the stack pointer index. It can only shrink the stack, never grow it. |
LATEST |
( -- addr ) |
Pushes the address of the most recent definition. |
13. Dictionary manipulation
src/word_source/dictionary_manipulation_words.c. Header-field words work on raw header addresses. They exist for
FIG and FORTH-79 compatibility; take care with them.
| Word | Stack | Description |
|---|---|---|
' |
( "name" -- xt ) |
Parses name and pushes its xt. It is not IMMEDIATE; inside a definition, use [']. |
FIND |
( "name" -- xt | 0 ) |
Parses from the input stream, not from a counted string on the stack. It pushes the entry, or 0 if the word is not found (a miss is not an error). For a counted string already in memory, use (FIND) from §14. |
SMUDGE |
( -- ) |
CO. Toggles the smudge (hidden) bit on the latest word. |
HIDDEN |
( -- ) |
CO. Sets the latest word's hidden bit (unlike SMUDGE, it does not toggle). |
>BODY |
( xt -- addr ) |
Pushes the address of the parameter (data) field. |
>NAME |
( xt -- nfa ) |
Pushes the name field. |
NAME> |
( nfa -- xt ) |
Goes from the name field to the xt. |
>LINK |
( xt -- lfa ) |
Pushes the link field. |
LINK> |
( lfa -- xt ) |
Follows the link to the next (older) word. |
CFA LFA NFA PFA |
( addr -- addr' ) |
FIG-style field-address conversions (code, link, name, and parameter fields). |
TRAVERSE |
( addr n -- addr' ) |
Moves across a name field forward (n=1) or backward (n=-1). |
INTERPRET |
( -- ) |
Runs the text interpreter on the rest of the current input. |
14. Vocabularies
src/word_source/vocabulary_words.c
| Word | Stack | Description |
|---|---|---|
VOCABULARY |
( "name" -- ) |
Creates a vocabulary. Running name later makes it the CONTEXT (search) vocabulary. |
DEFINITIONS |
( -- ) |
Sets CURRENT to CONTEXT, so new definitions go into the vocabulary being searched. |
CONTEXT |
( -- addr ) |
Pushes the address of the search-vocabulary pointer. |
CURRENT |
( -- addr ) |
Pushes the address of the definition-vocabulary pointer. |
FORTH |
( -- ) |
Makes the root FORTH vocabulary the context. |
ORDER |
( -- ) |
Prints the search order (CONTEXT, then FORTH) and CURRENT. |
(FIND) |
( c-addr -- c-addr 0 | xt 1 | xt -1 ) |
Looks up a counted string in CONTEXT and then in FORTH. It returns 1 for an IMMEDIATE word, -1 for a normal word, and 0 if not found. |
Example: VOCABULARY GRAPHICS GRAPHICS DEFINITIONS : BOX ... ; FORTH DEFINITIONS
15. System
src/word_source/system_words.c
| Word | Stack | Description |
|---|---|---|
( IMM |
( "ccc<)>" -- ) |
Starts a comment that runs to the closing ). |
\ IMM |
( "ccc<eol>" -- ) |
Starts a comment that runs to the end of the line. |
EXECUTE |
( xt -- ) |
Runs the word identified by xt. |
NOP |
( -- ) |
Does nothing. |
QUIT IMM |
( -- ) ( R: … -- ) |
Clears the return stack and the error flag and returns to the outer interpreter. The data stack is kept. It is refused (sets an error) inside a definition. |
ABORT |
( … -- ) |
Clears both stacks and returns to the interpreter. It is not reported as an error. |
ABORT" IMM |
( flag "ccc<">" -- ) |
If flag is non-zero, prints the message and runs ABORT. It works in both interpret and compile mode. |
(ABORT") |
( flag addr u -- ) |
Runtime for a compiled ABORT". The compiler inserts it; you do not call it directly. |
COLD |
( -- ) |
Clears both stacks and the error flag, returns to interpret mode, and moves HERE back to 1024 if it is higher. Dictionary headers are not removed; this is a minimal cold start. |
WARM |
( -- ) |
Clears both stacks and the error flag and returns to interpret mode. HERE and the dictionary are kept. |
BYE |
( -- ) |
Leaves this VM. In a child VM it halts the VM and returns to the parent's REPL. On Hera, the kernel's BYE from §34 takes precedence. |
REBOOT |
( c-addr u -- ) |
Sets the boot arguments and does a cold reset. Interpret mode only. |
SAVE-SYSTEM |
( -- ) |
Takes a simple snapshot of the start of VM memory. |
WORDS |
( -- ) |
Lists the words in the current vocabulary. |
VLIST |
( -- ) |
Gives a detailed word listing. |
SEE |
( "name" -- ) |
Decompiles and shows a definition. |
PAGE |
( -- ) |
Clears the screen. |
79-STANDARD |
( -- flag ) |
Pushes -1 when FORTH-79 compliance mode is on. |
16. Line editor
src/word_source/editor_words.c. The editor works on block SCR as 16 lines of 64 characters.
| Word | Stack | Description |
|---|---|---|
L |
( u -- ) |
Prints line u (0–15) of the current screen. |
S |
( c-addr len u -- ) |
Replaces line u with the string, padding with spaces or truncating to 64 characters. |
SHOW |
( -- ) |
Prints the whole screen with line numbers. |
EDIT |
( u -- ) |
Opens a minimal stdin/stdout line-editor shell on block u. |
17. Defining words and the compiler
src/word_source/defining_words.c
| Word | Stack | Description |
|---|---|---|
: IMM |
( "name" -- ) |
Starts a colon definition and switches to compile mode. The new word stays hidden until ;. |
; IMM |
( -- ) |
Compiles EXIT, ends the definition, reveals the word, and returns to interpret mode. |
CREATE |
( "name" -- ) |
Makes a header whose runtime pushes its data-field address (HERE aligned to a cell). It allocates no space, so follow it with ALLOT or ,. |
VARIABLE |
( "name" -- ) |
Makes a word that pushes the address of one newly allocated cell. |
CONSTANT |
( x "name" -- ) |
Makes a word that pushes x. |
DOES> IMM |
( -- ) |
Inside a defining word, ends the create part. Words later made by that defining word run the code after DOES> with their body address on the stack. |
IMMEDIATE IMM |
( -- ) |
Marks the latest definition IMMEDIATE. |
STATE |
( -- addr ) |
Pushes the address of the compile-state cell (0 means interpreting). |
[ IMM |
( -- ) |
Switches to interpret mode inside a definition. |
] IMM |
( -- ) |
Switches to compile mode. |
LITERAL IMM |
( x -- ) |
Compiles x so that it is pushed at runtime. Typical use: [ 6 7 * ] LITERAL. |
LIT |
( -- x ) |
Runtime for literals: pushes the next inline cell. The compiler inserts it; you do not call it directly. |
COMPILE IMM |
( "name" -- ) |
Legacy form: compiles a call to name. |
[COMPILE] IMM |
( "name" -- ) |
Compiles name even when it is IMMEDIATE. |
FORGET |
( "name" -- ) |
Removes name and every newer word and moves HERE back. Words below FENCE cannot be forgotten. |
FENCE |
( -- ) |
Moves the FORGET boundary up to the current top of the dictionary. A capsule calls it after loading to protect its own words. |
does_rt |
– | Internal DOES> helper that switches the new child word to DODOES. It is registered only so the threaded code can refer to it; do not call it. |
Example: : ARRAY ( n "name" -- ) CREATE CELLS ALLOT DOES> ( i -- addr ) SWAP CELLS + ;
18. Control flow
src/word_source/control_words.c. Every structure word is IMM and CO. Branch offsets are in bytes. Up to 64
structures can be nested at compile time (CF_STACK_MAX).
| Word | Stack | Description |
|---|---|---|
IF |
( flag -- ) |
Runs the following code only if flag is non-zero. It compiles (0BRANCH). |
ELSE |
( -- ) |
Starts the code that runs when the IF flag was zero. |
THEN |
( -- ) |
Ends an IF or IF … ELSE structure. |
BEGIN |
( -- ) |
Marks the start of a loop. |
UNTIL |
( flag -- ) |
Loops back to BEGIN while flag is zero. |
AGAIN |
( -- ) |
Loops back to BEGIN unconditionally. Leave with EXIT or ABORT. |
WHILE |
( flag -- ) |
In BEGIN … WHILE … REPEAT, leaves the loop when flag is zero. |
REPEAT |
( -- ) |
Jumps back to BEGIN and resolves the exit of WHILE. |
DO |
( limit start -- ) ( R: -- limit index ) |
Starts a counted loop that always runs at least once. |
?DO |
( limit start -- ) |
Like DO, but skips the loop body when start = limit. |
LOOP |
( -- ) |
Adds 1 to the index and loops while index < limit. |
+LOOP |
( n -- ) |
Adds n to the index. For n ≥ 0 it continues while index < limit; for n < 0 it continues while index ≥ limit. |
LEAVE |
( -- ) |
Exits the innermost DO loop immediately: it sets the index to the limit and jumps past LOOP. |
I |
( -- index ) |
Pushes the index of the innermost loop. It is not IMMEDIATE. |
J |
( -- index ) |
Pushes the index of the next outer loop. |
UNLOOP |
( -- ) ( R: limit index -- ) |
Drops the loop parameters. Use it before EXIT inside a DO loop. |
EXIT |
( -- ) |
Returns from the current colon definition. Using it in interpret mode is an error. |
CASE |
( x -- x ) |
Starts a case structure. |
OF |
( x v -- | x ) |
If x = v, drops both and runs the clause; otherwise keeps x and skips to the next OF. |
ENDOF |
( -- ) |
Ends an OF clause and jumps to ENDCASE. |
ENDCASE |
( x -- ) |
Drops the selector and resolves every ENDOF jump. |
(BRANCH) |
( -- ) |
Runtime: unconditional relative branch. The compiler inserts it; you do not call it directly. |
(0BRANCH) |
( flag -- ) |
Runtime: branches when flag is 0. The compiler inserts it; you do not call it directly. |
(DO) (?DO) |
( limit start -- ) |
Runtime for loop entry. The compiler inserts them; you do not call them directly. |
(LOOP) (+LOOP) |
( -- ) / ( n -- ) |
Runtime for loop increment and test. The compiler inserts them; you do not call them directly. |
(LEAVE) |
( -- ) |
Runtime for LEAVE: sets index to limit. The compiler inserts it; you do not call it directly. |
Examples:
: COUNTDOWN ( n -- ) BEGIN DUP . 1- DUP 0= UNTIL DROP ;
: TABLE ( -- ) 5 0 DO 5 0 DO I J * 4 .R LOOP CR LOOP ;
: COLOR ( n -- ) CASE 0 OF ." red" ENDOF 1 OF ." green" ENDOF ." ?" ENDCASE ;
19. StarForth extensions
src/word_source/starforth_words.c. These words are registered in both FORTH and the STARFORTH vocabulary.
| Word | Stack | Description |
|---|---|---|
ENTROPY@ |
( xt -- n ) |
Pushes the execution_heat counter of a word. The name says "entropy", but the value is execution heat. Registered only in the STARFORTH vocabulary. |
ENTROPY! |
( n xt -- ) |
Sets a word's execution_heat counter. Registered only in the STARFORTH vocabulary. |
WORD-ENTROPY |
( -- ) |
Prints the execution heat of every word. |
RESET-ENTROPY |
( -- ) |
Sets every heat counter to zero. |
TOP-WORDS |
( n -- ) |
Prints the n hottest words. |
(- |
( "ccc<)>" -- ) |
A comment that marks metadata blocks to extract into init.4th. It consumes input up to ). |
INIT |
( -- ) |
Reads ./capsules/core/init.4th, copies its blocks from block 1 onward, and runs them. |
VERSION |
( -- ) |
Prints StarForth v<ver> <arch> <variant> <timestamp>. |
SEED |
( n -- ) |
Seeds the PRNG so random sequences can be reproduced. |
RANDOM |
( lo hi -- n ) |
Pushes a pseudo-random number in [lo, hi], including both ends. |
WAIT |
( n -- ) |
Waits n heartbeat ticks by calling vm_tick() n times. It counts heartbeats, not wall-clock time, so it behaves the same on amd64, aarch64, and riscv64. |
HEARTBEAT-TICKS@ |
( -- n ) |
Pushes the canonical heartbeat tick count (Loop #7). The project uses this as its clock. It is read-only. |
ZUSE-AUTHENTICATE |
( -- ) |
Sets zuse_session = 1. The write happens only in C. |
ZUSE-SESSION? |
( -- flag ) |
True if ZUSE-AUTHENTICATE has run during this boot. It is read-only. |
ZUSE-PUBKEY@ |
( i -- u ) |
Pushes 8-byte little-endian chunk i (0–3) of Zuse's Ed25519 public key. An out-of-range i pushes 0 and sets an error. The private seed is never exposed. |
ZUSE-CERT-INSTALLED? |
( -- flag ) |
True once the one-time certificate fuse has been blown. |
20. Word-level ACL
src/word_source/acl_words.c. Every word takes an xt, obtained with ' or [']. Writes are silently ignored for
a pinned word.
| Word | Stack | Description |
|---|---|---|
ACL-MODE@ |
( xt -- mode ) |
Pushes the enforcement mode: 0 is STRICT (the decision is permanent) and 1 is TTL (the decision is rechecked when the countdown expires). |
ACL-MODE! |
( mode xt -- ) |
Sets the enforcement mode. |
ACL-TTL@ |
( xt -- n ) |
Pushes the TTL countdown. At 0 in TTL mode, the interpreter calls acl_recheck(). |
ACL-TTL! |
( n xt -- ) |
Sets the TTL, clamped to [0, UINT32_MAX]. |
ACL-ALLOW@ |
( xt -- flag ) |
Pushes the cached decision: -1 means allowed and 0 means denied. |
ACL-ALLOW! |
( flag xt -- ) |
Sets the cached decision; any non-zero value means allowed. |
ACL-PINNED? |
( xt -- flag ) |
True if the ACL fields are pinned and therefore immutable. |
ACL-PIN |
( xt -- ) |
Pins the word. This is one-way: no FORTH word can unpin it. |
ACL-HEAT@ |
( xt -- heat ) |
Pushes the execution heat. ACL.4th uses it to calibrate TTLs. |
ACL-WORD-ID |
( xt -- id ) |
Pushes the word's stable word_id. It never changes, so it is safe to use as a table index. |
ACL-INHERIT |
( src-xt dst-xt -- ) |
Copies the mode from src to dst and resets dst: unpinned, TTL 0, allowed. It is written in C because only C may clear a pin. |
ACL-INIT-PRIMITIVES |
( -- ) |
For every unpinned word, sets TTL to 0, allow to 1, and mode to TTL. ACL-BOOT calls it. |
21. Physics: benchmark and diagnostics
src/word_source/physics_benchmark_words.c. These are interactive diagnostics that print to the console.
| Word | Stack | Description |
|---|---|---|
BENCH-DICT-LOOKUP |
( iterations -- ) |
Benchmarks dictionary lookup and records Q48.16 latencies. Use at least 10,000 iterations; 100,000 is the standard run and 1,000,000 is a stress test. |
PHYSICS-CACHE-STATS |
( -- ) |
Prints hot-words cache statistics. |
PHYSICS-TOGGLE-CACHE |
( -- ) |
Turns the hot-words cache on or off, for A/B testing. |
PHYSICS-RESET-STATS |
( -- ) |
Resets the cache statistics. |
PHYSICS-BUILD-INFO |
( -- ) |
Prints the variant's build configuration. |
PHYSICS-BAYESIAN-REPORT |
( addr -- ) |
Prints a Bayesian comparison of the current cache statistics against the baseline stored at addr. |
physics_diagnostic_words.calso definesPHYSICS-WORD-METRICS,PHYSICS-CALC-KNOBS,PHYSICS-BURN ( n -- )andPHYSICS-SHOW-FEEDBACK, but nothing callsregister_physics_diagnostic_words(), so none of them are in the dictionary at this commit.
22. Physics: pipelining diagnostics
src/word_source/physics_pipelining_diagnostic_words.c
| Word | Stack | Description |
|---|---|---|
PIPELINING-SHOW-STATS |
( "name" -- ) |
Prints the word-to-word transition metrics of name. |
PIPELINING-SHOW-TOP-TRANSITIONS |
( "name" n -- ) |
Prints the n words that most often follow name. |
PIPELINING-ANALYZE-WORD |
( "name" -- ) |
Prints a full analysis of one word's transitions, with hints for reading them. |
PIPELINING-STATS |
( -- ) |
Prints pipelining statistics aggregated across the whole dictionary. |
PIPELINING-RESET-ALL |
( -- ) |
Clears all transition metrics. |
PIPELINING-ENABLE |
( -- ) |
Placeholder. Pipelining is switched on or off at compile time. |
23. Physics: freeze, heat, and decay
src/word_source/physics_freeze_words.c. Words are named by c-addr u strings, for example S" DUP" HEAT@. An
unknown name is not an error.
| Word | Stack | Description |
|---|---|---|
FREEZE-WORD |
( c-addr u -- ) |
Sets WORD_FROZEN on the word, so Loop #3 decay stops lowering its heat. |
UNFREEZE-WORD |
( c-addr u -- ) |
Clears WORD_FROZEN and leaves WORD_PINNED alone. |
FROZEN? |
( c-addr u -- flag ) |
True if the word is frozen. An unknown word gives 0. |
HEAT! |
( heat c-addr u -- ) |
Writes execution_heat directly, bypassing Loops #1 and #3. For testing only. |
HEAT@ |
( c-addr u -- heat ) |
Reads execution_heat. An unknown word gives 0. |
SHOW-HEAT |
( c-addr u -- ) |
Prints NAME: HEAT (frozen) (pinned). |
ALL-HEATS |
( -- ) |
Prints up to 1024 words sorted by heat, hottest first. |
DECAY-RATE@ |
( -- q ) |
Pushes the base decay rate per µs (DECAY_RATE_PER_US_Q16) in Q48.16. |
FREEZE-CRITICAL |
( -- ) |
Freezes 21 core words: DUP DROP SWAP OVER ROT @ ! C@ C! EXECUTE IF THEN ELSE DO LOOP BEGIN UNTIL REPEAT . EMIT CR. |
24. Dictionary heat optimisation
src/word_source/dictionary_heat_diagnostic_words.c
| Word | Stack | Description |
|---|---|---|
HEAT-PERCENTILES |
( -- p25 p50 p75 ) |
Pushes the current heat percentile thresholds, with the 75th on top. |
LOOKUP-STRATEGY@ |
( -- n ) |
Pushes the lookup strategy: 0 is naive (newest-first linear scan) and 1 is heat-aware (hot bucket first). |
LOOKUP-STRATEGY! |
( n -- ) |
Sets the strategy. Only 0 or 1 is accepted; other values are silently ignored. |
REORG-BUCKETS |
( -- ) |
Re-sorts the lookup buckets by heat and refreshes the percentiles immediately, without waiting for the heartbeat. |
SHOW-HEAT-OPTIMIZATION |
( -- ) |
Prints the strategy, the percentiles, and the hot, warm, and cool zones. |
COMPARE-LOOKUPS |
( iterations -- ) |
Benchmarks naive against heat-aware lookup and prints the speedup. It restores the original strategy afterwards. |
25. Logging
src/word_source/log_words.c
| Word | Stack | Description |
|---|---|---|
LOG-ERROR LOG-WARN LOG-INFO LOG-TEST LOG-DEBUG |
( -- level ) |
Push the log level constants. |
LOG-LEVEL! |
( level -- ) |
Sets the active log filter, clamped to [LOG-ERROR, LOG-DEBUG]. |
LOG-LEVEL@ |
( -- level ) |
Pushes the current log level. |
LOG-ERROR" LOG-WARN" LOG-INFO" LOG-TEST" LOG-DEBUG" IMM |
( "ccc<">" -- ) |
Log a literal string at that level. In interpret mode the string is logged immediately; when compiling, a runtime word and the inline string are compiled. |
LOG-ERROR-STR LOG-WARN-STR LOG-INFO-STR LOG-TEST-STR LOG-DEBUG-STR |
( c-addr u -- ) |
Log a string taken from the stack at that level. |
(do-log-error) (do-log-warn) (do-log-info) (do-log-test) (do-log-debug) |
( -- ) |
Runtimes for the compiled LOG-*" words. The compiler inserts them; you do not call them directly. |
(LOG-APPEND-RAW) K |
( level timestamp c-addr u -- ) |
Appends a raw entry to the kernel log ring, attributed to the calling VM (or HADES). It reports errors on the console, not through log_message, to avoid recursion. |
Example: : CHECK ( n -- ) 0< IF LOG-WARN" negative input" THEN ;
26. Q48.16 fixed-point math
src/word_source/q48_words.c. A value is n × 65536. The underlying type is unsigned uint64_t; see
§36 for what that means for negative values.
| Word | Stack | Description |
|---|---|---|
Q.+ Q.- |
( q1 q2 -- q3 ) |
Add and subtract. |
Q.* |
( q1 q2 -- q3 ) |
Multiplies, computing (a*b) >> 16. |
Q./ |
( q1 q2 -- q3 ) |
Divides, computing (a << 16) / b. Division by zero returns 0 and sets no error. |
Q.ABS |
( q -- |q| ) |
Absolute value, treating the top bit as a sign bit. |
Q.NEG |
( q -- -q ) |
Two's-complement negation. |
Q.LOG |
( q -- ln q ) |
Natural logarithm by Newton-Raphson. Requires q > 0. |
Q.EXP |
( q -- e^q ) |
Exponential by Taylor series. |
Q.SQRT |
( q -- √q ) |
Square root by Newton-Raphson. |
Q.SIN Q.COS |
( q -- q' ) |
Sine and cosine of an angle in radians. The argument is reduced to [-π, π] and then a Taylor series is applied. |
Q.FROM-INT |
( n -- q ) |
Converts an integer to Q48.16 as n << 16. A negative n becomes 0. |
Q.TO-INT |
( q -- n ) |
Converts to an integer as q >> 16, truncating. |
Q.1 |
( -- 65536 ) |
Pushes 1.0. |
Q.0 |
( -- 0 ) |
Pushes 0.0. |
Q.SCALE |
( -- 65536 ) |
Pushes the scale factor; the same value as Q.1. |
Q.= |
( q1 q2 -- flag ) |
Equality. |
Q.< Q.> |
( q1 q2 -- flag ) |
Comparison, done unsigned. |
Q.0= |
( q -- flag ) |
True if the value is zero. |
Q.MAX Q.MIN |
( q1 q2 -- q3 ) |
Maximum and minimum, compared unsigned. |
Q.PRINT |
( q -- ) |
Prints the value as int.fffff with five fractional digits. |
Example: 3 Q.FROM-INT Q.SQRT Q.PRINT prints approximately 1.732.
27. Inference engine (SSM, L8, and Bayes)
src/word_source/inference_words.c
| Word | Stack | Description |
|---|---|---|
INFER-RUN |
( -- ) |
Runs the full inference engine on this VM's rolling window and dictionary heat, and caches the results. |
INFER-WINDOW@ |
( -- u ) |
Pushes the last inferred optimal window width. |
INFER-DECAY@ |
( -- q ) |
Pushes the last inferred decay slope. |
INFER-VARIANCE@ |
( -- q ) |
Pushes the last inferred variance. |
INFER-FIT@ |
( -- q ) |
Pushes the last fit quality. |
INFER-EARLY-EXIT@ |
( -- flag ) |
True if the last run exited early. |
Q.VARIANCE |
( addr u -- q ) |
Pushes the variance of u uint64 cells at addr. |
INFER-DECAY-SLOPE |
( addr u -- q ) |
Fits a decay slope to the array by linear regression. |
INFER-WINDOW-WIDTH |
( addr u -- n ) |
Computes the optimal window width for the array. |
WINDOW-DIVERSITY |
( -- u ) |
Pushes the number of distinct words in the rolling window. |
L8-MODE |
( -- n ) |
Pushes the current L8 (legacy 16-mode) Jacquard selection. |
L8-UPDATE |
( entropy cv temporal stability -- ) |
Feeds four Q48.16 metrics to ssm_l8_update(). stability is on top of the stack. |
L8-APPLY |
( -- ) |
Applies the currently selected L8 mode. |
L8-TABLE-FORCE |
( idx -- ) |
Forces the adaptive 128-config table to idx & 127 as though the UCB bandit had picked it, and applies it. Unlike L8-UPDATE and L8-APPLY, this choice is not overwritten at the next heartbeat trial. Use it for DoE campaigns. |
BAYES-CACHE-MEAN BAYES-CACHE-LOWER BAYES-CACHE-UPPER |
( -- q ) |
Push the posterior mean latency and the 95 % credible bounds for hot-words cache hits. |
BAYES-BUCKET-MEAN BAYES-BUCKET-LOWER BAYES-BUCKET-UPPER |
( -- q ) |
Push the same three values for bucket searches. |
28. DEFER and IS
src/word_source/defer_words.c
| Word | Stack | Description |
|---|---|---|
DEFER |
( "name" -- ) |
Creates a vectored word. Running it before an action has been set with IS sets vm->error. |
IS |
( xt "name" -- ) |
Sets the action of name. It is refused unless name was created by DEFER. |
DEFER@ |
( "name" -- xt ) |
Pushes the current action of a deferred word. |
Example: DEFER GREET : HI ." hi" ; ' HI IS GREET GREET
29. Framebuffer (Hestia only)
src/word_source/framebuffer_words.c. These words are registered only in the Hestia VM, by capsule_birth_baby(),
and not by register_forth79_words().
| Word | Stack | Description |
|---|---|---|
PLOT |
( x y color -- ) |
Writes one raw pixel. The origin is top-left and Y increases downward. |
FB-WIDTH |
( -- n ) |
Pushes the framebuffer width in pixels. |
FB-HEIGHT |
( -- n ) |
Pushes the framebuffer height in pixels. |
30. Keyboard
src/word_source/keyboard_words.c. These are diagnostics for the console fabric. On a platform without the device,
each word pushes 0.
| Word | Stack | Description |
|---|---|---|
KBD-SCAN |
( -- sc -1 | 0 ) |
amd64 i8042: pops one raw XT scancode from the queue, if there is one. |
KBD-DEBUG |
( -- isr spurious ) |
amd64: pushes the i8042 interrupt count and the spurious-interrupt count. |
VKBD-EVENT |
( -- code value -1 | 0 ) |
riscv64 and aarch64 virtio-input: pops one Linux-style EV_KEY code and value. |
VKBD-DEBUG |
( -- isr ) |
riscv64 and aarch64: pushes the virtio-input interrupt count. |
KEY-EVENT |
( -- keycode pressed -1 | 0 ) |
The unified event on every architecture: pops one keycode with its pressed (1) or released (0) state. |
ALT+TAB |
( -- ) |
Switches the console between text and graphics, the same as the physical Alt+Tab. |
31. TrueType text
src/word_source/ttf_words.c
| Word | Stack | Description |
|---|---|---|
TTF-TEXT K |
( c-addr u x y size color -- ) |
Draws the string with the TrueType renderer at pixel (x, y) in the given size and color. |
32. REPL scrollback
src/word_source/scroll_words.c
| Word | Stack | Description |
|---|---|---|
SCROLL-BACK K |
( n -- ) |
Scrolls the REPL view back n lines. |
SCROLL-FWD K |
( n -- ) |
Scrolls the REPL view forward n lines, toward the live output. |
33. Kernel REPL and DoE hooks
src/starkernel/repl.c and src/starkernel/doe_log.c
| Word | Stack | Description |
|---|---|---|
HB-ON K |
( -- ) |
Turns on per-tick DoE instrumentation. |
HB-OFF K |
( -- ) |
Turns off per-tick DoE instrumentation. |
BLK-ATTACH-ACK K |
( dev-ptr ok? -- ) |
The acknowledgement Artemis sends to Hera after BLK-ATTACH, delivered with VM-EXEC. On success, Hera runs the deferred Zuse or WIREBIND attach. |
KH-BLK-ATTACH-SEND K |
( c-addr u -- ok? ) |
Sends a payload to Hera through kernel-Hermes. The sender and receiver are worked out in C, so the caller cannot spoof them. A refused send is logged. |
KH-ELEVATE-SEND K |
( c-addr u -- ok? ) |
The same mechanism for elevation requests. Nothing calls it at present. |
34. Hera (Mama) and child-VM words
src/starkernel/capsule/mama_forth_words.c. These are K only. Hera receives every word in this section, in
both FORTH and the MAMA vocabulary. Child VMs receive only STOP EXEC USE BIRTH CAPSULE-BIRTH VM-EXEC VM-CALL VM-HEAT VM-ERROR? SWITCH-MARK-WORK and the STADIUM-* words. VM names are matched without regard to case.
VM lifecycle
| Word | Stack | Description |
|---|---|---|
BIRTH |
( c-addr u -- ) |
Births a VM from its capsule (S" Artemis" loads artemis:init.4th). If the VM is already live, nothing happens. Hera is rejected. |
KILL |
( c-addr u -- ) |
Destroys a VM. Hera cannot be killed, and killing a dead VM does nothing. |
START |
( c-addr u -- ) |
Enters the VM's REPL and blocks until it runs STOP or BYE. It refuses a VM that is LIVE, DEAD, or STILLBORN. |
STOP |
( -- ) |
Halts the current VM, so its REPL loop returns. |
USE |
( c-addr u -- ) |
Redirects console input to the named VM without nesting the C stack, and changes the prompt to [Name]. S" Hera" USE switches back to Hera. |
EXEC |
( c-addr u -- ) |
Runs a named capsule inside the current VM. |
EJECT |
( -- ) |
Cleanly detaches the identity attached through USB home blocks: it flushes the user VM and kills it, or logs Zuse out. |
CONNECT-HERMES |
( -- ) |
Enters Hermes's REPL, birthing Hermes first if needed. |
CONNECT-ARTEMIS |
( -- ) |
Enters Artemis's REPL, birthing Artemis first if needed. |
BYE |
( -- ) |
On Hera: reaps every child and then cold-resets the machine. |
Cross-VM execution (compudynamics)
| Word | Stack | Description |
|---|---|---|
VM-EXEC |
( cmd-a cmd-u name-a name-u -- ) |
Injects a command into the named VM and runs it immediately without blocking. Example: S" DOE-WORK" S" Hermes" VM-EXEC. |
VM-CALL |
( cmd-a cmd-u name-a name-u -- n ) |
Like VM-EXEC, then pops the target's top of stack onto the caller's stack. If the target left nothing, it pushes 0 and sets an error. |
VM-STEP |
( c-addr u -- ) |
Gives the named VM one REPL turn: one prompt, one line, then it returns. |
VM-HEAT |
( c-addr u -- q ) |
Pushes the VM's execution_heat_q48. An unknown VM gives 0 and prints nothing. |
VM-ERROR? |
( c-addr u -- flag ) |
True if the VM has vm->error set. An unknown VM gives 0. |
VM-COUNT |
( -- n ) |
Pushes the number of registered VMs. |
VM-CONSERVED? |
( -- flag ) |
True if the total fleet heat is within ε of Q.1. |
VM-PHYSICS-STATUS |
( -- ) |
Prints the fleet physics report. |
SWITCH-MARK-WORK |
( c-addr u -- ) |
Marks a VM as having work, which makes it eligible for a context switch. The message path calls it, and it ignores bad names silently. |
MAMA-VM-ID |
( -- 0 0 ) |
Pushes Hera's 128-bit VM ID, which is all zeros. |
NAME>XT |
( c-addr u -- xt | 0 ) |
Looks up a name held in a data buffer. A miss gives 0. |
Capsules
| Word | Stack | Description |
|---|---|---|
CAPSULE-COUNT |
( -- n ) |
Pushes the number of entries in the capsule directory. |
CAPSULE@ |
( idx -- desc | 0 ) |
Pushes the descriptor for the capsule at idx. |
CAPSULE-HASH@ |
( desc -- hash ) |
Pushes the capsule's content hash. |
CAPSULE-FLAGS@ |
( desc -- flags ) |
Pushes the capsule's flags. |
CAPSULE-LEN@ |
( desc -- len ) |
Pushes the capsule's payload length. |
CAPSULE-BIRTH |
( id -- vmid-lo vmid-hi ) |
Births an unnamed VM from a production (p) capsule and pushes its 128-bit ID. On failure both cells are all ones. |
CAPSULE-RUN |
( id -- ) |
Runs an experiment (e) capsule on Hera. |
CAPSULE-TEST |
( -- ) |
Prints a message confirming the capsule system is running. |
WORKER-BIRTH |
( cap-a cap-u name-a name-u -- ok? ) |
Births a named, VM-EXEC-addressable worker from any p-capsule, with no identity attached. |
UNATTENDED-BIRTH |
( cap-a cap-u name-a name-u -- ok? ) |
Births a VM and installs the verified identity whose UNATTENDED-ID-UUID and UNATTENDED-ID-CERT the capsule defined. |
CONSOLE-ATTACH |
( name-a name-u -- ok? ) |
Pairs a new console VM with the live VM registered as <name>~user. |
Identity, Zuse, and diagnostics
| Word | Stack | Description |
|---|---|---|
MINT |
( fn-a fn-u un-a un-u em-a em-u ph-a ph-u restrict? -- ok? ) |
Mints an identity onto the attached USB drive. The full name and username are required; pass an empty string for email or phone to leave them out. A non-zero restrict? selects the locked-down personality that allows only FORTH-79 and FORTH-83 words. |
MINT-SCRATCH |
same as MINT |
Mints onto the scratch device instead, prints the UUID, and pushes 1 or 0. |
MINT-SCRATCH-EMIT |
( -- ok? ) |
Prints the last scratch mint as FORTH source (CREATE UNATTENDED-ID-UUID / -CERT byte lists) for copying by hand. It refuses (pushes 0) if no mint has succeeded. |
ZUSE-ELIGIBILITY-ADD |
( c-addr -- ok? ) |
Adds the 32-byte Ed25519 public key at c-addr to Zuse's elevation list. |
ZUSE-ELIGIBLE? |
( c-addr -- flag ) |
Checks whether a key is on the list. It fails closed. |
ELEVATE-PUBKEY-UNPACK |
( pk0 pk1 pk2 pk3 buf -- ) |
Rebuilds a 32-byte public key from four cells. It is the inverse of ZUSE-PUBKEY@. |
RUNCAP-TEST |
( c-addr u -- ok? rc ) |
Diagnostic: runs capsule_runcap_birth() against the current home-blocks drive. |
PAIR-TEST |
( c-addr u -- ok? ) |
Diagnostic: births a console VM and a <name>~user VM as a pair. |
Stadium (heat accounting)
Heat values are Q48.16. Each word works only on the calling VM's own quota.
| Word | Stack | Description |
|---|---|---|
STADIUM-ADMIT |
( identity heat behaviour -- cell | -1 ) |
Admits a patron. behaviour must be 0–3. |
STADIUM-EVICT |
( cell -- flag ) |
Reaps the patron in cell. It is refused if the cell is out of range, not resident, pinned, or blocked by what it contains. |
STADIUM-HEAT@ |
( cell -- heat ) |
Reads a resident cell's heat. A cell that is not the caller's gives 0. |
STADIUM-HEAT! |
( heat cell -- ) |
Writes a cell's heat, pulling the difference from the reservoir or pushing it back. An increase the reservoir cannot cover is silently refused. |
STADIUM-RES@ |
( -- heat ) |
Pushes the VM's reservoir balance. |
STADIUM-RES-PULL |
( qty -- got ) |
Pulls up to qty from the reservoir and pushes the amount actually taken. |
STADIUM-RES-PUSH |
( heat -- ) |
Credits heat back to the reservoir. |
STADIUM-WORD-HEAT |
( -- heat ) |
Pushes the total heat held by this VM's word-execution residents. |
35. Hosted lifecycle stubs
src/word_source/lifecycle_words_hosted.c. These are H only; main.c registers them. Each word only logs
"<WORD> <name> (hosted)". They exist so that capsule scripts also parse in hosted builds.
| Word | Stack | Description |
|---|---|---|
BIRTH KILL PAUSE RESUME USE |
( c-addr u -- ) |
No-op stubs that only write a log line. |
36. Implementation quirks to know
These behaviours differ from what a FORTH-79 or ANS programmer would expect. Each was checked against the C source.
ROLLcounts from the bottom of the stack. With1 2 3on the stack,1 ROLLgives2 3 1; ANS gives1 3 2. The test suite (stack_words_test.c) asserts the current behaviour, so it looks intended. Portable code should useSWAPandROT.PICKis 0-based, as in ANS. FORTH-79'sPICKwas 1-based.FINDparses the input stream. It does not take a counted string. Use(FIND)for a counted string orNAME>XT(kernel only) for a name in a buffer.- The Q48.16 type is unsigned.
Q.<,Q.>,Q.MIN,Q.MAXandQ.PRINTtreat a negative Q value as a huge positive one, andQ.FROM-INTturns a negative integer into 0.Q.ABSandQ.NEGdo treat the top bit as a sign. Q./by zero returns 0 without setting an error, while the integer/,MOD, and*/all setvm->error.[LITERAL]does nothing, andLITERALworks only because §17 registers it again after the placeholder.MOD,/MOD,*/, and*/MODare registered twice. The mixed-arithmetic versions (§6) are the ones used.- Four
PHYSICS-*diagnostic words are not registered.PHYSICS-WORD-METRICS,PHYSICS-CALC-KNOBS,PHYSICS-BURNandPHYSICS-SHOW-FEEDBACKare defined in C but never added to the dictionary. does_rtis a visible dictionary entry. It is an internal helper; do not call it.- The
STARFORTHvocabulary registers its words twice (once inFORTH, once inSTARFORTH). Hera does the same withMAMA. As a result, those names appear twice inWORDSoutput.