blob: c508a8505143b58515833c678401b3098a47eb81 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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
```
|