sema

package
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 18, 2026 License: GPL-3.0 Imports: 11 Imported by: 0

Documentation

Overview

Package sema lowers a parse tree to the resolved semantic model in the ir package: it resolves names, lowers sugar to prelude types, and interns type references.

It is private and free to change. `ir` and `proto` are the compatibility surface, not this.

See docs/design/ir-plan.md for what each pass adds: the declaration table, the interned type and unit tables, scopes and shadowing, the recursion rules, imports, classes and instances, constraints, and targets.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Diagnostic

type Diagnostic struct {
	Pos ast.Position
	Msg string
}

Diagnostic is one problem found while lowering, at a source position.

func (*Diagnostic) Error

func (d *Diagnostic) Error() string

type Diagnostics

type Diagnostics []*Diagnostic

Diagnostics is every problem one pass found.

A pass reports all of them rather than stopping at the first, the way the parser reports every syntax error. A non-empty list means no later pass should run: every diagnostic it produced against a model this one rejected would be noise.

func Lower

func Lower(file *ast.File, opts ...Option) (*ir.Model, Diagnostics)

Lower turns a parsed file into a model. It returns the model and every diagnostic the pass produced; a non-empty diagnostic list means the model is incomplete and no later pass should run against it.

The prelude is loaded into an outer scope, so a file may declare a name the prelude already has and its own declaration wins.

func (Diagnostics) Error

func (ds Diagnostics) Error() string

type FSLoader

type FSLoader struct{}

FSLoader resolves an import as a filesystem path relative to the file that imports it, which is what the spec says a bare path means.

func (FSLoader) Load

func (FSLoader) Load(from, path string) (string, string, error)

type Loader

type Loader interface {
	// Load returns the resolved name of the file imported as path from the
	// file at from, and its source.
	Load(from, path string) (name, src string, err error)
}

Loader reads the source of an imported file.

Lowering does not touch the filesystem itself, so a caller can supply dependency roots, an in-memory tree, or a vendored directory without lowering knowing about any of it.

type Option

type Option func(*config)

Option configures a lowering.

func WithLoader

func WithLoader(l Loader) Option

WithLoader supplies the Loader that reads imported files. Without one, a file that imports anything is a diagnostic rather than a filesystem read nobody asked for.

func WithPrelude

func WithPrelude(name, src string) Option

WithPrelude lowers against the given prelude source instead of the embedded one. Pointing at a replacement is what makes the prelude replaceable rather than built in.

func WithReferences added in v0.2.2

func WithReferences(out *References) Option

WithReferences records every name lowering resolves into out.

Recording is opt-in because nothing but an editor wants it: `tdl check` and `tdl gen` resolve the same names and throw the answers away, and they should keep doing that rather than allocate a table nobody reads.

type Reference added in v0.2.2

type Reference struct {
	Pos  ast.Position // where the name was written
	Len  int          // its length in bytes, so a caller can underline it
	Name string       // the name as written

	// Target is where what the name refers to was declared, and is zero
	// when there is nowhere to go: a name that did not resolve has none,
	// and neither does a qualified one, whose declaration is in a
	// dependency this model parsed for its names and not for its
	// positions. A name a `_` import merged in has the position it was
	// declared at, in the dependency that declares it.
	Target ast.Position

	// Decl is the declaration the name refers to, for a caller that wants
	// the model entry rather than a position. It is unset for a type
	// parameter, which declares nothing, and for an unresolved name.
	Decl *ir.ID
}

Reference is one name, as written, and what it resolved to.

Lowering resolves every name and then keeps only the answer's effect: a type reference is interned into the type table, and the table is keyed by structure, so the second mention of a name is not a second entry and a cursor on it has nothing to find. This records the question instead, which is what a "go to definition" is asking.

Target is where to go. It is where the name was bound rather than a position derived later, so the ladder that decided what a name means, shadowing, the prelude, and `_` imports, is applied once, by the code that already applies it.

type References added in v0.2.2

type References []Reference

References is every name one lowering resolved, in source order.

func (References) At added in v0.2.2

func (rs References) At(filename string, offset int) (Reference, bool)

At returns the reference covering a byte offset in a file, and whether there is one.

References are sorted, so this is a binary search rather than a walk: an editor asks this on every hover, and a model is not small.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL