## OCaml Modal Interpreter A minimal, AST-based Modal interpreter. See the language overview in the project root `README.md` and reference `ocaml/REF.txt`. Original docs: [Modal in a Postcard](https://wiki.xxiivv.com/site/modal). ### Build ``` opam switch create . ocaml-base-compiler.5.2.1 --no-install && opam install . --deps-only -y && dune build @install ``` ### Run Pass a rules file and an optional input expression: ``` dune exec modal -- examples/logic.modal "(eq fox bat) (eq bat bat)" ``` Or rely on input lines inside the file (lines starting with `..`): ``` dune exec modal -- examples/devices.modal ``` Flags: - `-q`: quiet (suppress device prints; still prints final tree) - `-a`: allow file/stdin devices (`(?_)`, `(?~)`) - `-n`: large cycle cap (effectively “no limit”) ### Implementation highlights - AST rewrite engine with left-to-right preorder scan; rule order is significant. - Dynamic rules during evaluation using explicit list forms: - Define: `(<>) (left) (right)` - Undefine: `(><) (left) (right)` - Registers: `?name` unify on the left and substitute on the right. - Devices (side-effect hooks): - `(?: ...)` print or ALU: `(?: + 1 2 3)` → `6`; otherwise concatenates arguments to stdout, returns `()`. - `(?_) path` import file (requires `-a`); returns parsed AST if possible else an atom. - `(?~)` read stdin (requires `-a`); returns atom of contents or `EOF`. - `(?^) x` join atoms from `x` into a single atom. - `(?.) x` unwrap list `x` into its elements. - `(?*) x` explode atom `x` into list of character atoms; lists pass through unchanged. - Cycle cap and flags implemented in the evaluator. Notes on semantics vs C version: - This interpreter uses an AST scan rather than a raw token stream. Most programs work as expected; exact stream-boundary edge cases may differ. - Lambda `?(...)` is not implemented yet; easy to add if needed. ### Examples ``` # Devices (printing, ALU, join/unwrap/explode) dune exec modal -- examples/devices.modal # Dynamic rules (define/undefine during evaluation) dune exec modal -- -q examples/dynamic_rules.modal # Arithmetic (via ?:) dune exec modal -- examples/arith.modal ```