bind

package
v1.5.12 Latest Latest
Warning

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

Go to latest
Published: Mar 3, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package bind implements name resolution and symbol binding for Lua AST nodes.

The binding phase occurs after parsing and before type checking. It resolves all identifier references in the AST to unique SymbolIDs, establishing the connection between uses of a name and its declaration.

The binder performs lexical scope analysis using a scope stack. Each scope frame tracks local variable declarations. Name lookup searches from innermost to outermost scope, implementing Lua's lexical scoping rules:

  • Local variables shadow outer declarations of the same name
  • Undeclared variables become implicit globals
  • Function parameters create a new scope for the function body
  • Loop variables (for statements) are local to the loop body
  • repeat-until condition can see variables declared in the loop body

The binding process handles several Lua-specific behaviors:

  • Method definitions (function obj:method()) receive an implicit 'self' parameter
  • Local function definitions are predeclared to support mutual recursion
  • Expressions on the right side of 'local x = expr' see the outer scope
  • Generic for loops can declare multiple iteration variables

The result is a BindingTable that maps AST nodes to their resolved symbols, enabling subsequent compiler phases to work with unique symbol identities rather than string names.

Package bind provides name resolution for Lua programs.

The binder traverses AST nodes and resolves identifier references to unique symbols. This establishes the binding between uses and definitions, enabling type checking and CFG construction to work with stable identities.

Symbol Assignment

Symbols are assigned to:

  • Local variables at their declaration point
  • Function parameters at function entry
  • For loop iteration variables at loop entry
  • Global references (assumed external)
  • Field paths like M.f.g (each qualified access gets a symbol)

Usage

Call Bind with a function AST and optional global names:

bindings := bind.Bind(funcExpr, "print", "error", "assert")

The returned BindingTable provides:

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FieldPathKeyFromSegments added in v1.5.6

func FieldPathKeyFromSegments(segs []constraint.Segment) (string, bool)

FieldPathKeyFromSegments converts path segments into the canonical binder key format.

Canonical format is constraint.FormatSegments output, e.g.:

  • .field
  • .a.b
  • ["a.b"]
  • [1]

func NormalizeFieldPathKey added in v1.5.6

func NormalizeFieldPathKey(path string) (string, bool)

NormalizeFieldPathKey canonicalizes legacy dotted paths into binder key format.

Legacy dotted form:

  • f
  • a.b

Canonical form:

  • .f
  • .a.b
  • ["a.b"]
  • [1]

Types

type Binder

type Binder struct {
	// contains filtered or unexported fields
}

Binder performs name resolution by walking the AST and assigning unique SymbolIDs to all identifier declarations and references.

The binder maintains a stack of scope frames to implement lexical scoping. The bottom frame (index 0) holds global variables. Each function body, block statement, and loop body pushes a new frame.

Usage:

table := bind.Bind(functionAST, predeclaredGlobals)
sym, ok := table.SymbolOf(someIdentifier)

func NewBinder

func NewBinder(globals []string) *Binder

NewBinder creates a binder initialized with predeclared global names.

The globals parameter specifies names that should be treated as predefined global variables (e.g., "print", "pairs", "ipairs"). These are placed in the bottom scope frame and receive SymbolGlobal kind.

Globals are sorted before processing to ensure deterministic SymbolID assignment across multiple bindings of the same source.

func NewBinderWithDeclHint added in v1.5.11

func NewBinderWithDeclHint(globals []string, declHint int) *Binder

NewBinderWithDeclHint creates a binder initialized with global names and an optional declaration-count hint for sizing internal binding maps.

func NewBinderWithStmtHint added in v1.5.11

func NewBinderWithStmtHint(globals []string, stmtHint int) *Binder

NewBinderWithStmtHint preserves the previous API surface; stmtHint is treated as a declaration-density hint.

type BindingTable

type BindingTable struct {
	// contains filtered or unexported fields
}

BindingTable stores the results of name resolution for a Lua program.

The table provides bidirectional mapping between AST nodes and symbols:

  • IdentExpr nodes map to their resolved SymbolID
  • FunctionExpr nodes map to their parameter symbols
  • LocalAssignStmt nodes map to their declared local symbols
  • For loop statements map to their iteration variable symbols

Each symbol has an associated kind (global, local, param) and name. The table also supports field paths (M.f.g) and anonymous function symbols.

BindingTable is the primary output of the binding phase and is consumed by type checking and CFG construction phases.

func Bind

func Bind(fn *ast.FunctionExpr, globals []string) *BindingTable

Bind performs complete name resolution on a function AST.

This is the main entry point for the binding phase. It creates a binder with the specified predeclared globals, processes the entire function (including nested functions), and returns the resulting BindingTable.

The returned table maps all IdentExpr nodes to their resolved symbols and records parameter/local symbol lists for each function and declaration.

func NewBindingTable

func NewBindingTable() *BindingTable

NewBindingTable creates an empty binding table with all maps initialized.

func NewBindingTableWithHint added in v1.5.11

func NewBindingTableWithHint(symbolHint, stmtHint int) *BindingTable

NewBindingTableWithHint creates a binding table with optional size hints.

symbolHint estimates total symbols in the bound unit (locals/params/globals), while stmtHint estimates top-level statement volume.

func (*BindingTable) AllSymbols

func (t *BindingTable) AllSymbols() []cfg.SymbolID

AllSymbols returns every symbol in the table without duplicates.

This collects symbols from all sources: bound identifiers, kinds map, parameter lists, local declarations, and for loop variables. Zero symbols are excluded.

func (*BindingTable) Bind

func (t *BindingTable) Bind(ident *ast.IdentExpr, sym cfg.SymbolID)

Bind records that an identifier references a specific symbol.

func (*BindingTable) CapturedSymbols

func (t *BindingTable) CapturedSymbols(fn *ast.FunctionExpr) []cfg.SymbolID

CapturedSymbols identifies free variables in a function.

A captured symbol is one that is referenced inside the function body but declared outside it. This includes both upvalues (locals from enclosing functions) and globals.

The analysis walks the function body to find all referenced symbols, then subtracts symbols declared within the function (parameters and locals).

func (*BindingTable) FieldSymbol

func (t *BindingTable) FieldSymbol(baseSym cfg.SymbolID, path string) (cfg.SymbolID, bool)

FieldSymbol looks up an existing symbol for a field path. Returns zero and false if no symbol exists for the given base and path.

func (*BindingTable) FuncLitBySymbol

func (t *BindingTable) FuncLitBySymbol(sym cfg.SymbolID) (*ast.FunctionExpr, bool)

FuncLitBySymbol returns the function literal for a symbol if known.

func (*BindingTable) FuncLitSymbol

func (t *BindingTable) FuncLitSymbol(fn *ast.FunctionExpr) (cfg.SymbolID, bool)

FuncLitSymbol returns the symbol for a function literal if one exists.

func (*BindingTable) GenericForSymbols

func (t *BindingTable) GenericForSymbols(stmt *ast.GenericForStmt) []cfg.SymbolID

GenericForSymbols returns the iteration variable symbols for a generic for.

func (*BindingTable) GetOrCreateFieldSymbol

func (t *BindingTable) GetOrCreateFieldSymbol(baseSym cfg.SymbolID, path string) cfg.SymbolID

GetOrCreateFieldSymbol returns or creates a symbol for a qualified field path.

Field paths represent nested property access like M.f or M.f.g. The baseSym identifies the root object, and path is the dot-separated field chain.

The created symbol gets a composite name (e.g., "M.f") and SymbolLocal kind. Subsequent calls with the same base and path return the existing symbol.

func (*BindingTable) GetOrCreateFuncLitSymbol

func (t *BindingTable) GetOrCreateFuncLitSymbol(fn *ast.FunctionExpr) cfg.SymbolID

GetOrCreateFuncLitSymbol returns or creates a symbol for an anonymous function.

Anonymous functions (function literals) need symbols for type assignment and reference tracking. Each unique FunctionExpr AST node gets its own symbol.

func (*BindingTable) Globals

func (t *BindingTable) Globals() []cfg.SymbolID

Globals returns all symbols with SymbolGlobal kind. This includes both predeclared globals and implicitly created globals.

func (*BindingTable) HasLocalSymbols added in v1.5.11

func (t *BindingTable) HasLocalSymbols(stmt *ast.LocalAssignStmt) bool

HasLocalSymbols reports whether local symbols were recorded for stmt.

func (*BindingTable) Kind

func (t *BindingTable) Kind(sym cfg.SymbolID) (cfg.SymbolKind, bool)

Kind returns the declaration kind of a symbol. Returns false if the symbol has no recorded kind.

func (*BindingTable) LocalSymbolAt added in v1.5.11

func (t *BindingTable) LocalSymbolAt(stmt *ast.LocalAssignStmt, i int) (cfg.SymbolID, bool)

LocalSymbolAt returns the i-th symbol declared by a local assignment.

func (*BindingTable) LocalSymbols

func (t *BindingTable) LocalSymbols(stmt *ast.LocalAssignStmt) []cfg.SymbolID

LocalSymbols returns the symbols declared by a local assignment.

func (*BindingTable) Name

func (t *BindingTable) Name(sym cfg.SymbolID) string

Name returns the source name of a symbol, or empty if unknown.

func (*BindingTable) NumForSymbol

func (t *BindingTable) NumForSymbol(stmt *ast.NumberForStmt) (cfg.SymbolID, bool)

NumForSymbol returns the iteration variable symbol for a numeric for.

func (*BindingTable) ParamSymbols

func (t *BindingTable) ParamSymbols(fn *ast.FunctionExpr) []cfg.SymbolID

ParamSymbols returns the parameter symbols for a function in declaration order.

func (*BindingTable) SetFuncLitSymbol

func (t *BindingTable) SetFuncLitSymbol(fn *ast.FunctionExpr, sym cfg.SymbolID)

SetFuncLitSymbol assigns a specific symbol to a function literal.

func (*BindingTable) SetGenericForSymbols

func (t *BindingTable) SetGenericForSymbols(stmt *ast.GenericForStmt, syms []cfg.SymbolID)

SetGenericForSymbols records the iteration variables for a generic for loop. For 'for k, v in pairs(t) do ... end', this records symbols for k and v.

func (*BindingTable) SetKind

func (t *BindingTable) SetKind(sym cfg.SymbolID, k cfg.SymbolKind)

SetKind records whether a symbol is a global, local, or parameter.

func (*BindingTable) SetLocalSymbol added in v1.5.11

func (t *BindingTable) SetLocalSymbol(stmt *ast.LocalAssignStmt, sym cfg.SymbolID)

SetLocalSymbol records the symbol declared by a single-name local assignment.

func (*BindingTable) SetLocalSymbols

func (t *BindingTable) SetLocalSymbols(stmt *ast.LocalAssignStmt, syms []cfg.SymbolID)

SetLocalSymbols records the symbols declared by a local assignment. For 'local a, b, c = ...', the symbols correspond to a, b, c in order.

func (*BindingTable) SetName

func (t *BindingTable) SetName(sym cfg.SymbolID, name string)

SetName records the source name associated with a symbol.

func (*BindingTable) SetNumForSymbol

func (t *BindingTable) SetNumForSymbol(stmt *ast.NumberForStmt, sym cfg.SymbolID)

SetNumForSymbol records the iteration variable for a numeric for loop. For 'for i = 1, 10 do ... end', this records the symbol for 'i'.

func (*BindingTable) SetParamSymbols

func (t *BindingTable) SetParamSymbols(fn *ast.FunctionExpr, syms []cfg.SymbolID)

SetParamSymbols records the ordered parameter symbols for a function. For methods with implicit self, self is the first symbol in the list.

func (*BindingTable) SymbolOf

func (t *BindingTable) SymbolOf(ident *ast.IdentExpr) (cfg.SymbolID, bool)

SymbolOf returns the symbol that an identifier reference resolves to. Returns zero and false if the identifier is nil or not bound.

func (*BindingTable) SymbolsByName added in v1.5.6

func (t *BindingTable) SymbolsByName(name string) []cfg.SymbolID

SymbolsByName returns all symbols recorded with the given source name.

Results are sorted by symbol ID for deterministic iteration.

Jump to

Keyboard shortcuts

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