You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The bridge.eph integration target for #43.
After this commit, `cargo run -- compile-eph bridge.eph` produces
~2.2KB of wasm output for the vendored hypatia bridge fixture
(`tests/v2-grammar/fixtures/hypatia-port/bridge.eph`).
Resolver
--------
- **Module-declaration index.** The import resolver now scans `base_dir`
for every `.eph` file at startup, reads the first `module a/b/c` line
of each, and builds a name → file-path map. `import a/b/c` first
tries the literal `<base>/a/b/c.eph` path; on miss, falls back to the
index. Lets corpora like hypatia's `src/ui/gossamer/` keep flat
filenames (`hypatia_gui.eph`) while their declared module name
(`hypatia/ui/gui`) drives import resolution.
Language additions
------------------
- **`pub data Foo = ...`.** Grammar now accepts `visibility?` before
`data` declarations.
- **Record/sum type aliases.** `type Foo = { f1: T1, f2: T2 }` and
`type Bar = | A | B(I32)` previously failed at parse. Records lower
to right-nested binary products; sums lower to right-nested binary
sums.
- **Record literal field separators.** `record_field_assign` accepts
three surface forms — `f: ty = v`, `f = v`, and `f: v` (ML-style
shorthand). Records lower to positional pairs / tuples.
- **`type Foo = T` alias resolution in desugar.** New `type_aliases`
map on `DataRegistry` captures alias bodies in surface form;
`desugar_named_type` looks them up and recursively expands.
- **`pub` keyword in `parse_data_decl`** — was being eaten as the data
type name.
- **Match-on-literal lowering.** `match n of | 0 => a | 1 => b | _ => c`
desugars to nested `if scrutinee == lit then arm else next` ending
in the default branch. Required by bridge.eph's `int_to_department`
and `decode_msg`.
- **Bare string literals.** Desugar wraps `Literal::String(s)` as
`StringNew { region: "_", value: s }`. The typechecker's region-
activation gate exempts `_` (the wildcard region for inferred String
types).
- **Nullary fn signatures expose as `() -> T`.** `fn foo(): T = ...` was
previously registered as having type `T` directly, making `foo()` at
a call site fail to unify. Three pre-pass / registry call sites
updated.
Vendored fixture
----------------
`tests/v2-grammar/fixtures/hypatia-port/{bridge,hypatia_gui}.eph` are
local adaptations of hypatia's upstream files. Four changes versus
upstream (all documented in the file headers):
1. `module hypatia/ui/gui` header on hypatia_gui.eph
2. `pub` keywords on items bridge.eph imports
3. `model.field_name` rewritten as positional `.0` / `.1` (named
field access remains future work)
4. `decode_msg` reparses bytes per use so each linear `String` is
consumed exactly once
Tests
-----
- `src/ephapax-cli/tests/v2_grammar_phase_j.rs::bridge_eph_compiles_end_to_end`
— spawns `ephapax compile-eph`, asserts return code 0, output ≥1KB
starting with wasm magic bytes.
Note: full `wasmparser::validate` does not yet pass on the bridge
output — ADT-constructor / match-arm codegen produces a stack
mismatch ("expected i32, nothing on stack") which is left for a
follow-up. Parse + typecheck + binary emission are all covered.
- `cargo test --workspace` clean, no regressions on the existing
~40 test binaries.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
0 commit comments