Parse type/enum/union declaration syntax + scope resolution#177
Merged
Conversation
Reserved keywords type/enum/union, parsed into new NodeKind::Type/Enum/
Union ({ params, sep, body }, mirroring Fn). Covers:
- type: record (named fields), tuple (positional), unit (type _), generic
(type T:)
- enum T: closed-sum members (nullary + payload-carrying)
- union: block of member types
- ..Foo type-level spread (extension) in all three block bodies
Reuses existing parsers: record bodies are rec-literal arms (Arm ':'),
tuple/enum/union bodies are expr lists, spreads reuse parse_spread. Parse
+ AST + both source formatters + partial-desugar transform wired; CPS
panics (not yet lowered), scopes registers generic params + walks the
body, layout todo!. Parse-only: no type-decl semantics downstream yet.
New fixture test_types.fnk (9 tests).
Walk type-declaration bodies with keyword-specific name semantics so the
editor does not flag declared names as unbound:
- type: record field names are declarations (not resolved); field types,
tuple positionals, and ..Foo extensions resolve as type references.
- union: members resolve as references to existing types.
- enum: members MINT constructors -- the constructor name binds, payload
types resolve against the generic params.
Generic params bind in a child scope. New walk_type_member helper handles
the per-keyword member shapes. Fixture test_scope_types.fnk (3 tests).
Add ScopeKind::Type(kw) carrying the keyword so type/enum/union bodies render as 'type'/'enum'/'union' rather than the misleading 'fn'. Behaves like Fn for the non-module binding checks; only the display label differs.
|
📦 This PR will release v0.86.0 (minor) when merged. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds parsing and scope resolution for
type/enum/uniondeclaration syntax. This is the parser + name-resolution foundation that lets the VSCode extension (grammar / LSP) recognize type declarations without flagging declared names as unbound.Parse-only at the AST/scopes level: no desugar/CPS/codegen semantics for type declarations yet (a declaration reaching CPS panics cleanly; no current path does). Downstream lowering — nominal identity, subtyping, construction, match-on-type — is future work.
What landed
Parser + AST (
feat(ast)): three reserved keywords parsed into newNodeKind::Type/Enum/Union({ params, sep, body }, mirroringFn):type:record (named fields), tuple (positional), unit (type _), generic (type T:)enum T:closed-sum members (nullary + payload-carrying)union:block of member types..Footype-level spread (extension) in all three block bodiesReuses existing parsers — record bodies are rec-literal arms, tuple/enum/union bodies are expr lists, spreads reuse
parse_spread. Both source formatters, the partial-desugar transform, and the walker are wired.Scopes (
feat(scopes)): keyword-specific name resolution so the editor does not flag declared names as unbound:type:— record field names are declarations (not resolved); field types, tuple positionals, and..Fooresolve as type references.union:— members resolve as references to existing types.enum:— members mint constructors (the constructor name binds; payload types resolve against the generic params).'type'/'enum'/'union') via a newScopeKind::Type(kw).Testing
Full suite green: 1345 lib + 42 CLI + 1 interop, 0 failed. New fixtures:
test_types.fnk(9 AST tests) andtest_scope_types.fnk(3 scope tests).Follow-ups
A or B(inline union),union T1, T2, T3(call form).Foo {…}/Ni 1, 2/Some 12), match-on-type patterns, member access / destructure (these reuse existing grammar but aren't yet pinned by tests).