writeonce/compiler/README.md
shoney.arickathil 2de724df11 feat(compiler): MVS ownership pass + woc driver; drop Money/SKU/Float, reject abstract
Completes plan 2 Tasks 7-8. owner.ml: mutable-value-semantics flow analysis
producing the four plan-3 emitter tables (moves, drops incl. LIVE-MASK for trap
unwinding, rc with elision, residual borrow sites) plus WO-E301-304 two-site
diagnostics. Alias questions run over canonicalized places, so a double-mut
reached through let-bound aliases lands in the residual table like the direct
form; dump.ml's contract notes the emitter must coalesce guards per operand.
main.ml: directory discovery, cross-file programs (symbols merge before bodies
check), diagnostics ordered by (file,line,col), new WO-E214 for a name declared
in two files. New docs/plan/oop-vm/01-error-catalog.md (14 emitted + 10 reserved
codes), un-ignored so both plan tracks can cite it; justfile regains woc-*.

builtin_scalars is now the five that work: Int, Bool, Text, Timestamp, Id.
Money/SKU/Float and the abstract_types allowlist are gone — `abstract` never
lexed, and Float had no literal syntax and no wob kind, so no value could exist.
Fixtures and samples retype Money->Int, SKU->Text. The abstract newtype feature
is rejected outright (verdict row adopt->reject); haxe-parity Task 7 keeps `is`.

nullable-types-implementation.md corrected: ?T is plumbed but UNENFORCED
(E211-213 declared, never emitted; probe exits 0), handed to haxe-parity Task 6
as next work item. Records all 10 dead codes incl. E205 — interface satisfaction
is unchecked. crates/rt keeps its Money/SKU fixtures (opaque strings, Stage 2).

Gate: build warning-clean, 14 + 264 checks 0 failures, pricing golden exit 0,
docs/examples histograms unchanged (13/70, zero WO-E225).
2026-08-10 21:24:50 +02:00

42 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# compiler/ — the OCaml `woc` compiler
Lexer → parser → typechecker → ownership pass, for `.wo`. OCaml stdlib only (no Menhir, no ppx); dune is the build runner. Sibling of the C `wovm` bytecode VM (`runtime/`) — the two halves of the OOP track's spec (`docs/superpowers/specs/2026-08-01-oop-compiler-vm-design.md`) meet at plan 3 (`.wob` emission; not built yet).
**Stage: plan 2 (`docs/plan/compiler/2026-08-01-woc-compiler-front.md`) complete, Tasks 1–8.** Diagnostics, lexer, parser (declarations + statements/expressions), typechecker (symbols, field kinds, structural interfaces, `?T` nullable), and the MVS ownership pass are all implemented and wired into the `woc` executable. Bytecode emission and `.wob` output are plan 3 — not started.
## Requirements
OCaml 4.14.1, dune 3.14.0 — Ubuntu 24.04 apt packages (`sudo apt install ocaml dune`), the version floor. Confirm with `ocaml -version` / `dune --version`. No opam packages, no Menhir, no ppx — stdlib only.
## Build, test
```bash
cd compiler && dune build # -> _build/default/bin/woc
cd compiler && dune runtest # test_diag unit checks + runner golden/CLI-smoke suite
just woc-build # same, from the repo root
just woc-test # same, from the repo root
```
`WOC_BLESS=1 dune runtest` (from `compiler/`) rewrites golden `.expected` files to match current output — use it once, by hand, to seed or intentionally update a fixture.
## Running `woc`
```
woc <path> # compile (lex, parse, typecheck, ownership-check); nothing prints on success
woc --dump-tokens <path> # stdout: one line per lexed token
woc --dump-ast <path> # stdout: the declaration + body AST, indented
woc --dump-owner <path> # stdout: the ownership pass's four tables (moves, drops, rc, residual)
```
`<path>` is a single `.wo` file or a directory. A directory is discovered recursively for every `.wo` file under it — same contract as `wo run` (`crates/rt/src/lib.rs::discover`): dot-prefixed entries and `target`/`data`/`node_modules` are skipped, results are sorted by path. Every discovered file compiles as one program (declarations in one file resolve for bodies in another, regardless of discovery order); diagnostics from every file and every stage print sorted by `(file, line, col)`. For multi-file `--dump-*` output, each file's dump is preceded by a `=== path ===` header line (`compiler/src/dump.ml`'s `file_header`) — a single-file run never prints one.
Diagnostics render as `file:line:col: severity CODE: message` plus a source excerpt with a caret; every shipped code is cataloged in `docs/plan/oop-vm/01-error-catalog.md`. Exit codes: **0** clean compile, **1** diagnostics reported, **2** usage/IO failure.
## Layout
- `src/` — one module per stage: `diag` (diagnostics, collector, exit-code decision), `token`/`lexer`, `ast`/`parser`, `types` (typechecker), `owner` (MVS ownership pass), `dump` (stable text dumps for all of the above)
- `bin/` — the `woc` executable: CLI parsing, file discovery, the multi-file/cross-file driver
- `test/` — `runner.ml` (golden runner + CLI smoke) and `test_diag.ml` (diag.ml unit checks); `test/golden/<stage>/` holds one-file-per-fixture goldens (`tokens`, `ast`, `owner`, `owner-err`); `test/fixtures/driver/` holds the multi-file CLI-smoke fixtures (directory discovery, cross-file symbols, diagnostic ordering) that don't fit the one-`.wo`-file-per-fixture golden shape
Governing docs (all under `docs/`, not here — this file stays an orientation README): spec `docs/superpowers/specs/2026-08-01-oop-compiler-vm-design.md`; plan `docs/plan/compiler/2026-08-01-woc-compiler-front.md` (+ `architecture.md`, `nullable-types-implementation.md`, `2026-08-01-haxe-parity-language.md`, `2026-08-01-wob-emit-e2e-single-binary.md` in the same directory). Format contract: `docs/plan/oop-vm/00-wob-format.md`. Error catalog: `docs/plan/oop-vm/01-error-catalog.md`.