diff options
Diffstat (limited to 'ocaml/NOCK_INTERPRETER.md')
| -rw-r--r-- | ocaml/NOCK_INTERPRETER.md | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/ocaml/NOCK_INTERPRETER.md b/ocaml/NOCK_INTERPRETER.md new file mode 100644 index 0000000..72998e5 --- /dev/null +++ b/ocaml/NOCK_INTERPRETER.md @@ -0,0 +1,13 @@ +# Nock Interpreter Notes + +## Design Intent +Starting from an empty tree let us rebuild the evaluator deliberately. The new `lib/nock.ml` is a clean-room implementation: a direct transcription of the Nock 12-opcode semantics into idiomatic OCaml. I leaned on the published definition, the behaviour I observed in Vere’s `pkg/noun/nock.c`, and Sword’s `rust/sword/src/interpreter.rs` to double-check edge cases (axis addressing, opcode 9 call flow, and the atom/cell guards). No source code was copied; the module was written from scratch against a fresh `noun.ml` scaffold. + +## Contrast With `ocaml-old/lib/nock.ml` +- **Trampoline vs. straight recursion**: the previous interpreter preserved C Vere’s tail-call trampoline, logging, and jet hooks. The new version omits those for now; each opcode executes recursively with OCaml’s own call stack. This keeps the baseline tiny and easier to audit while we stand the project back up. +- **Instrumented logging removed**: the old file embedded depth counters, mug tracing, and selective opcode logging. Those features hid the essential control flow. The rewrite strips everything to the semantic cores; diagnostics can be reintroduced as optional layers later. +- **Jet integration postponed**: legacy code dispatched through `Jets.try_jet` inside opcode 9. In the reset implementation opcode 9 always evaluates the target by slot lookup and Nock. When we reintroduce jets we can do so behind a clearly typed interface instead of hand-off callbacks. +- **Hint/Edit parity kept simple**: opcodes 10 and 11 now delegate immediately to their second argument (matching Vere’s default fall-through) without the extra conditional scaffolding found in `ocaml-old`. + +## Rationale +Recreating the interpreter from first principles makes the behavioural contract explicit and keeps the code surface small enough to reason about before we add persistence, jets, or multicore scheduling. Referencing Vere and Sword informed the guard conditions and axis math, but the resulting OCaml is purpose-built for this reset. As the project matures we can layer back optimisations—tail-call trampolining, profiling, and jet dispatch—knowing they sit on top of a minimal, well-understood core.*** |
