about summary refs log tree commit diff stats
path: root/modal/ocaml/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'modal/ocaml/README.md')
-rw-r--r--modal/ocaml/README.md61
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