diff options
Diffstat (limited to 'modal/ocaml/README.md')
-rw-r--r-- | modal/ocaml/README.md | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/modal/ocaml/README.md b/modal/ocaml/README.md new file mode 100644 index 0000000..c508a85 --- /dev/null +++ b/modal/ocaml/README.md @@ -0,0 +1,61 @@ +## 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 +``` \ No newline at end of file |