Documentation
¶
Overview ¶
Package surface is Rune's named layer: the lexer, parser, named AST, the pretty-printer (core -> named surface), and name resolution (named surface -> locally-nameless core).
Names live here and only here. Resolution is the only "elaboration" in Phase 0: it sends bound identifiers to de Bruijn indices and free identifiers to definition references (content hashes). There is no type elaboration in Phase 0.
Index ¶
- Variables
- func DebugCore(t core.Tm) string
- func FreeIdents(e Exp) []string
- func Pretty(t core.Tm) string
- func PrettyWith(t core.Tm, refNames map[core.Hash]string) string
- func SpineOf(e Exp) (Exp, []Exp)
- type Ctor
- type DataDef
- type Def
- type EAnn
- type EApp
- type ECast
- type EEq
- type EHole
- type ELam
- type ELet
- type EPi
- type EProp
- type ERefl
- type ESubst
- type EUniv
- type EVar
- type Exp
- type Item
- type Resolver
Constants ¶
This section is empty.
Variables ¶
var ErrIncomplete = errors.New("incomplete input")
ErrIncomplete marks a parse that ran out of input mid-form (an unterminated is/seq block, or a binder/let awaiting more tokens). The REPL distinguishes it from a hard syntax error to decide between a continuation prompt and an error message.
Functions ¶
func DebugCore ¶ added in v0.2.0
DebugCore renders a core term in explicit locally-nameless form: bound variables as their de Bruijn index (#n), references as @hash, binders unnamed (λ, Π). It is the REPL's :core debug view and deliberately is not a sentence of the surface grammar.
func FreeIdents ¶
FreeIdents returns the free identifiers of e (those not bound by an enclosing lambda, Pi, or let), de-duplicated. The CLI uses this to build the definition dependency graph that drives SCC-ordered hashing.
func Pretty ¶
Pretty turns a core term back into named surface syntax. This is the inverse direction of the three-representation split: the core is locally nameless, and exactly the layer you read gets names back.
Bound variables are named from the Scope.Name hints carried for display, freshened on shadowing so the printed names never capture. Because names are reconstructed, parse . resolve . pretty . resolve is the identity on core up to the de Bruijn form — which is what the round-trip property asserts.
func PrettyWith ¶
PrettyWith is Pretty with a map from definition hashes to names, used to render Ref nodes as the names the user wrote. An unknown reference prints as #<hash>.
Types ¶
type DataDef ¶ added in v1.0.0
DataDef is a datatype declaration (Phase 4):
data Name : Ty is C1 : T1 | C2 : T2 | … end
type Def ¶
Def is one top-level definition: Name (: Ty)? = Body. The file is a flat list of these (no modules in Phase 0). Ty is nil when omitted.
type ECast ¶ added in v1.0.0
type ECast struct{}
ECast is the cast head, `cast`, saturated with four arguments: cast A B p x.
type EEq ¶ added in v1.0.0
type EEq struct{}
EEq is the equality former head, `Eq`. It is applied like a function and must be saturated with three arguments: Eq T l r.
type EHole ¶ added in v1.0.0
type EHole struct{}
EHole is `_`: a hole for elaboration to solve with a fresh metavariable (Phase 2). Holes never survive elaboration; the untyped resolver rejects them.
type ELam ¶
type ELam struct {
Param string
Icit core.Icit // Impl when written fn {x : A}
Qty core.Qty // 0 or 1 when annotated (fn (0 x : A) …); ω otherwise
Dom Exp
Body Exp
}
ELam is one parameter of a lambda: fn (Param : Dom) is Body end. The parser desugars a curried fn (x : A) (y : B) is e end into nested ELam. Dom is the binder's domain annotation; resolution scope-checks it and then discards it, since the Phase-0 core lambda is un-annotated (see GRAMMAR.md §6). Dom is never nil.
type EPi ¶
type EPi struct {
Param string
Icit core.Icit // Impl when written {x : A} -> B
Qty core.Qty // 0 or 1 when annotated ((0 x : A) -> B); ω otherwise
Dom Exp
Cod Exp
}
EPi is a dependent function type (Param : Dom) -> Cod. A non-dependent arrow A -> B parses to EPi with Param "_".
type EProp ¶ added in v1.0.0
type EProp struct{}
EProp is the universe of propositions, Prop (Phase 3).
type ERefl ¶ added in v1.0.0
type ERefl struct{}
ERefl is the reflexivity proof head, `refl`. Used bare (in checking position) or applied to one argument.
type ESubst ¶ added in v1.0.0
type ESubst struct{}
ESubst is the transport head, `subst`, saturated with six arguments: subst A x y p P px — from p : Eq A x y and px : P x, conclude P y.
type EUniv ¶
type EUniv struct {
Lvl int
}
EUniv is a universe: `U` is U_0, `U1`…`U9` the higher levels (Phase 6).
type EVar ¶
type EVar struct {
Name string
}
EVar is an identifier occurrence: either a bound variable or a free reference to a top-level definition. Resolution decides which.
type Exp ¶
type Exp interface {
// contains filtered or unexported methods
}
Exp is a named surface expression. Like core.Tm it is a sealed interface matched by type switch; the marker keeps the constructor set closed.
type Item ¶ added in v1.0.0
type Item interface {
// contains filtered or unexported methods
}
Item is one top-level program item: a *Def or a *DataDef.
func ParseProgram ¶ added in v1.0.0
ParseFile parses a flat list of top-level definitions (GRAMMAR.md §3). Each definition self-delimits with its own `end`, so no layout rule is needed; newlines between definitions are insignificant. ParseProgram parses a file of top-level items: definitions and datatype declarations, in order.
type Resolver ¶
Resolver carries the only context name resolution needs in Phase 0: a map from top-level definition names to their content hashes. Resolution is the sole "elaboration" in Phase 0 — it sends bound identifiers to de Bruijn indices and free identifiers to definition references. There is NO type elaboration here.