ocaml: phase 4 modules + field access (+11 tests, 215 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 54s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 54s
module M = struct DECLS end parsed by sub-tokenising the body source between struct and the matching end (nesting tracked via struct/begin/ sig/end). Field access is a postfix layer above parse-atom, binding tighter than application: f r.x -> (:app f (:field r "x")). Eval (:module-def NAME DECLS) builds a dict via ocaml-eval-module running decls in a sub-env. (:field EXPR NAME) looks up dict fields, treating (:con NAME) heads as module-name lookups instead of nullary ctors so M.x works with M as a module. Phase 4 LOC so far: ~110 lines (well under 2000 budget).
This commit is contained in:
@@ -179,7 +179,8 @@ SX CEK evaluator (both JS and OCaml hosts)
|
||||
|
||||
### Phase 4 — Modules + functors
|
||||
|
||||
- [ ] `module M = struct let x = 1 let f y = x + y end` → SX dict `{:x 1 :f <fn>}`.
|
||||
- [x] `module M = struct let x = 1 let f y = x + y end` → SX dict
|
||||
`{"x" 1 "f" <fn>}`.
|
||||
- [ ] `module type S = sig val x : int val f : int -> int end` → interface record
|
||||
(runtime stub; typed checking in Phase 5).
|
||||
- [ ] `module M : S = struct ... end` — coercive sealing (runtime: pass-through).
|
||||
@@ -187,7 +188,7 @@ SX CEK evaluator (both JS and OCaml hosts)
|
||||
- [ ] `module F = Functor(Base)` — functor application.
|
||||
- [ ] `open M` — merge M's dict into current env (`env-merge`).
|
||||
- [ ] `include M` — same as open at structure level.
|
||||
- [ ] `M.name` — dict get via `:name` key.
|
||||
- [x] `M.name` — dict get via field access.
|
||||
- [ ] First-class modules (pack/unpack) — deferred to Phase 5.
|
||||
- [ ] Standard module hierarchy: `List`, `Option`, `Result`, `String`, `Char`,
|
||||
`Int`, `Float`, `Bool`, `Unit`, `Printf`, `Format` (stubs, filled in Phase 6).
|
||||
@@ -321,6 +322,18 @@ the "mother tongue" closure: OCaml → SX → OCaml. This means:
|
||||
|
||||
_Newest first._
|
||||
|
||||
- 2026-05-08 Phase 4 — modules + field access (+11 tests, 215 total). Parser:
|
||||
`module M = struct DECLS end` decl in `ocaml-parse-program`. Body parsed
|
||||
by sub-tokenising the source between `struct` and the matching `end`,
|
||||
tracking nesting via `struct`/`begin`/`sig`/`end`. Field access added
|
||||
as a postfix layer above `parse-atom`, binding tighter than application:
|
||||
`f r.x` → `(:app f (:field r "x"))`. Eval: `(:module-def NAME DECLS)`
|
||||
builds a dict via new `ocaml-eval-module` that runs decls in a sub-env;
|
||||
`(:field EXPR NAME)` looks up the field, with the special case that
|
||||
`(:con NAME)` heads are interpreted as module-name lookups instead of
|
||||
nullary ctors. Tested: simple module, multi-decl module, nested modules
|
||||
(`Outer.Inner.v`), `let rec` inside a module, module containing tuple
|
||||
pattern match. Phase 4 LOC: ~110 (well under 2000 budget).
|
||||
- 2026-05-08 Phase 2 — `try`/`with` + `raise` builtin. Parser produces
|
||||
`(:try EXPR CLAUSES)`; eval delegates to SX `guard` with `else`
|
||||
matching the raised value against clause patterns and re-raising on
|
||||
|
||||
Reference in New Issue
Block a user