REPL
The KN-86 REPL is a built-in read-eval-print loop over the same Fe VM that runs cartridges, ships in firmware v1.0 alongside nEmacs (per ADR-0002 and ADR-0016, which unified the two as one subsystem with two buffer types). This page is the implementer-facing reference for loop semantics, history, error handling, output formatting, and cartridge access policy. Runtime engineers building the REPL and cartridge authors shipping documented snippets read this.
../../../adr/ADR-0002-player-facing-lisp.md— original commitment to a player-facing REPL, tutorial role, history budget, FFI exposure.../../../adr/ADR-0016-nemacs-repl-input-model.md— unified input model with nEmacs, keymap-as-Lisp-alist, context-polymorphic dispatch, multi-tap, double-tap / long-press.nemacs.md— sibling editor surface (shares keymap machinery and FFI).token-prediction.md,../fe-lisp/,README.md.
Subsystem identity
Section titled “Subsystem identity”Per ADR-0016, the REPL is not a separate subsystem from nEmacs — they are one editor subsystem with two buffer types. The REPL is the buffer type whose root sequence is “prompt + history” rather than “Lisp source under edit.” Same keymap machinery, same cursor model, same FFI bindings, same :tap / :double-tap / :long-press event model.
The differences from nEmacs (nemacs.md):
- Buffer organization: a prompt at the bottom and an immutable history above, rather than a single editable tree.
- Modes:
:repl-promptfor input composition,:repl-historyfor browsing past forms. - Eval timing: every committed form runs immediately and prints its result, vs. nEmacs’s explicit
eval-currentverb. - FFI policy: read-only against deck state; mutations forbidden (Tier 3 per ADR-0005).
Memory: 24 KB SRAM arena per ADR-0002, allocated when the REPL opens, released on exit. The cart that was active when the REPL opened is suspended; it resumes on REPL exit.
Read-eval-print loop semantics
Section titled “Read-eval-print loop semantics”Input composition uses the same structural primitives as nEmacs (nemacs.md §“Structural editing primitives”). The player builds the input expression as an s-expression tree with CONS (palette insertion), LAMBDA (literal entry via Nokia multi-tap, nemacs.md §“Literal entry”), and structural verbs (CAR descend, CDR next-sibling, BACK ascend).
The input is always a well-formed s-expression — there is no ambiguity around partial parens. When the player wants to submit, they press EVAL.
Submitted forms evaluate against the REPL’s Fe context. The Fe interpreter calls fe_eval. Errors are caught by the REPL’s installed fe_handlers->error (see ../fe-lisp/language-reference.md) — they do not propagate to firmware exit.
Tutorial mode (per ADR-0002) pre-loads a sequence of prompts that walk the player through CAR/CDR navigation of a toy list, QUOTE/EVAL, and defining their first lambda. Tutorial mode is a runtime configuration of the same REPL, not a separate subsystem.
The result is rendered into the history buffer using Fe’s fe_write with the REPL’s installed fe_WriteFn. Output goes into a fresh history entry above the prompt.
The print pass also routes the result through the toast overlay zone for the most recent value (see “Output formatting” below).
History buffer
Section titled “History buffer”Per ADR-0002, the REPL persists the last 32 expressions (input + result) to deck state. Recall semantics:
:repl-historymode: cursor is browsing past forms, not at the prompt.CDRadvances to the next history entry (older).- (Reverse direction is
prev-sibling, conventionally bound to long-pressCDRper thenemacs.mdverb table.) EVALon a history entry re-executes that input in the current REPL context.CARdescends into the entry to inspect / edit its form structurally before re-eval.
History persists across REPL sessions via deck state (microSD per ADR-0011). The 32-slot ring evicts oldest on overflow. Tutorial-mode prompts do not consume history slots — those are scripted prompts the runtime injects.
Error handling
Section titled “Error handling”Errors come in two flavors:
Recoverable (caught, REPL continues)
Section titled “Recoverable (caught, REPL continues)”The Fe error handler installed by the REPL catches fe_error calls — out-of-arena, type mismatches, unbound symbols, “too few arguments,” etc. — and:
- Renders the error message into the history buffer as a failed entry.
- Drops the partial result (no half-applied side effects since the REPL is Tier 3 read-only).
- Returns control to
:repl-promptmode with the input form preserved (so the player can edit and retry).
Per ../fe-lisp/memory-model.md, arena exhaustion in the REPL aborts the current expression but preserves history.
Fatal (REPL exits)
Section titled “Fatal (REPL exits)”Only one fatal mode: an unrecoverable Fe context state (e.g., GC stack overflow that corrupts the context). The REPL closes, the message is written to deck state’s diagnostic log, the cart resumes from suspension. In v1 this is treated as a runtime bug to be filed, not a normal failure.
Output formatting
Section titled “Output formatting”The REPL’s fe_WriteFn formats output into the history buffer with:
- Truncation. Long lists / strings truncate at the terminal width (CIPHER-LINE-aware — the modeline reserves Row 1; output flows into the main grid).
- Pretty-printing for nested forms. Forms over a single-line budget render structurally (one element per line, indented).
- Type tagging on opaque values. A
FE_TPTR(e.g., a cell handle) renders as#<ptr 0x1234>, not as raw bytes. - Symbols and numbers in canonical form. Numbers print as floats; integers print without a trailing
.0when the value is exact.
Toast overlay zone
Section titled “Toast overlay zone”Per the GWP-120 scaffold (referenced in ADR-0016’s known-unknowns and the original stub), the most recent REPL result also briefly displays in a transient overlay band above the prompt — a “toast” — to make the latest value scannable without scrolling history. The toast fades after a few seconds; the value remains in the history buffer permanently. Per the GWP-120 scaffold, exact toast duration and visual treatment land during the editor foundation task; treat as evolving.
Integration with nEmacs and token prediction
Section titled “Integration with nEmacs and token prediction”- Token prediction (
token-prediction.md) drives REPL completion at the prompt the same way it drives nEmacs’s palette. Cart-contributed grammar (emacs-extend-grammar) and vocabulary (emacs-extend-vocabulary) apply to both surfaces. - nEmacs ↔ REPL handoff — the player can author a snippet in nEmacs and want to test it in the REPL. The handoff binding is
SYS → Testor a dedicated key. Per ADR-0016 §“Known Unknowns” #6, the exact key binding is TBD pending the foundation implementation task. - Shared input event model —
:tap/:double-tap/:long-pressevents (ADR-0016 §9) are dispatched the same way; the REPL just binds different verbs in:repl-promptand:repl-historyscopes.
Cartridge access policy (Tier 3)
Section titled “Cartridge access policy (Tier 3)”Per ADR-0005 §“Tier 3 — REPL-Read-Only Primitives,” the REPL exposes only read-only access to the platform. Specifically allowed:
- State (read):
get-handle,get-credits,get-reputation,has-capability,deck-state. - Cells (inspect):
current-cell,list-get,list-length,is-leaf. - Procedural:
lfsr-seed,lfsr-next,lfsr-range(these mutate LFSR state but do not affect mission outcomes). - Display query:
display-mode.
Specifically forbidden:
- All
text-*,gfx-*,sound-*,sfx-*mutations (the REPL doesn’t compete with cart rendering). spawn-cell,destroy-cell,drill-into,navigate-back(cell pool / nav stack are runtime-owned).phase-advance,mission-complete,award-credits,modify-reputation,set-capability(mission state stays clean).cipher-push-event,cipher-emit,aux-*(CIPHER-LINE remains under the runtime’s control).- Fe’s
eval/ load / intern (per ADR-0007 Tier 3 — no dynamic code loading at runtime).
Rationale: the REPL is for exploration, debugging, and scripted automation that a cart author or sophisticated player wants to script. Mutating mission state from the REPL would silently corrupt the deck. If a player wants to mutate, they accept a contract — that’s the diegetic frame.
Tutorial mode
Section titled “Tutorial mode”Per ADR-0002, the REPL doubles as the platform’s Lisp tutorial. First-boot triggers a guided walkthrough:
- Toy list navigation with
CAR/CDR. QUOTEandEVALdistinction.- Defining a first lambda with
(fn ...). - Tutorial exits when the player demonstrates all three.
Tutorial prompts are runtime-injected into the prompt buffer; they are not history entries. The tutorial is a sequence of pre-loaded prompts plus expected-result checks, not a separate interactive subsystem. Players can exit tutorial mode at any time via SYS → Skip Tutorial.
What’s TBD
Section titled “What’s TBD”- Toast overlay duration and visual treatment (GWP-120 scaffold; lands during foundation task).
- REPL ↔ nEmacs handoff key binding (ADR-0016 known unknown #6).
- Whether tutorial-mode completion grants a capability bit or other deck-state marker (per ADR-0002 sign-off — implementation-time decision).