Skip to content

feat(v2): qualified module-member access M.member (G6 keystone)#331

Merged
hyperpolymath merged 2 commits into
mainfrom
claude/g6-module-imports
Jun 27, 2026
Merged

feat(v2): qualified module-member access M.member (G6 keystone)#331
hyperpolymath merged 2 commits into
mainfrom
claude/g6-module-imports

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Summary

Closes the parse half of G6, "the single highest-leverage v2 toolchain item" (docs/v2-grammar-and-codegen-gaps-2026-06-16.adoc). Phase I (#43) already made an imported module's public items visible unqualified (the cross-module test passes). This adds the qualified M.member syntax, which previously errored at the parser with "Named field access not yet supported".

The change (parser → surface AST → desugar)

  • Grammar (ephapax.pest): member_op accepts a constructor_name after ., so both M.fn (lower-case) and M.Ctor (upper-case) lex.
  • Surface AST: new SurfaceExprKind::FieldAccess { base, field }.
  • Parser (surface.rs): a named member access builds FieldAccess instead of erroring.
  • Desugar (ephapax-desugar): FieldAccess resolves against the importer's imports — M is the last path segment of an import (import lib/mathmath) — to the unqualified member, reusing phase I's shared scope:
    • upper-case member → constructor (Construct),
    • otherwise → function/value (Var).
    • Unknown qualifier → clean QualifiedAccessUnknownModule error; member access on a non-module base → rejected (record field access stays a follow-up).

Verified

  • New fixture tests/v2-grammar/fixtures/qualified-import/ + test src/ephapax-cli/tests/v2_grammar_phase_k_qualified.rs (2 tests): lib.inc(...) (qualified function), lib.On (qualified constructor), and unqualified inc (phase I) all compile end-to-end to wasm; an unknown qualifier is a clean error.
  • Full parser / desugar / surface / cli suites pass — no regressions (parser 62, etc.).
  • TEST-NEEDS.md count bumped 486 → 488.

Mapped to the doc

The G6 doc's first snippet (Coproc.available(Coproc.Tensor) not parsing) is exactly this: available=function→Var, Tensor=nullary constructor→Construct. Resolution note added to the gaps doc.

Follow-ups (documented, out of scope here)

  • M.Ctor(args) — qualified constructor with arguments currently lowers to App(Ctor, args), not Construct{Ctor,[args]}.
  • Record field access on values (value.field) — still unsupported.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AGFqWzByua4dKbA7W7oVsL


Generated by Claude Code

Closes the parse half of the G6 keystone gap (docs/v2-grammar-and-codegen-
gaps-2026-06-16.adoc). Phase I (#43) already made an imported module's
public items visible UNQUALIFIED; this adds the qualified `M.member`
SYNTAX, which previously errored at the parser with "Named field access
not yet supported".

- grammar: `member_op` accepts a `constructor_name` after `.` (so both
  `M.fn` and `M.Ctor` lex).
- surface AST: new `SurfaceExprKind::FieldAccess { base, field }`.
- parser: a named member access builds `FieldAccess` instead of erroring.
- desugar: `FieldAccess` resolves against the importer's imports — `M` is
  the last path segment of an `import` — to the unqualified member: an
  upper-case `member` desugars to a constructor (`Construct`), otherwise a
  function/value (`Var`), reusing phase I's shared scope. An unknown
  qualifier is a clean `QualifiedAccessUnknownModule` error; member access
  on a non-module base is rejected (record field access stays a follow-up).

Verified: `lib.inc(...)` (function) + `lib.On` (constructor) compile
end-to-end to wasm (new fixture tests/v2-grammar/fixtures/qualified-import/
+ test src/ephapax-cli/tests/v2_grammar_phase_k_qualified.rs, 2 tests).
Full parser/desugar/surface/cli suites pass — no regressions. Follow-ups:
`M.Ctor(args)` (lowers to App, not Construct-with-args) and record field
access on values.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGFqWzByua4dKbA7W7oVsL
@hyperpolymath
hyperpolymath marked this pull request as ready for review June 27, 2026 19:06
@hyperpolymath
hyperpolymath enabled auto-merge (squash) June 27, 2026 19:06
@hyperpolymath
hyperpolymath merged commit 02bf873 into main Jun 27, 2026
1 check passed
@hyperpolymath
hyperpolymath deleted the claude/g6-module-imports branch June 27, 2026 19:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants