Expand description
§symbol_lang
The name-resolution substrate for the -lang family: a lexically-scoped
SymbolTable that maps interned names to bindings, and ready-made
diagnostics for the two name errors every language reports. It is generic over
the binding — the language decides what a name resolves to — so one scope
engine serves every language built on it.
§Model
A resolver walks its own syntax tree and threads a SymbolTable: it enters a
scope on the way into a block, defines the names that
block introduces, lookups references outward through the
enclosing scopes, and exits the scope on the way out (or wraps the block in
scoped). A name resolves to the nearest enclosing
binding, so an inner definition shadows an outer one while its scope is open.
Names are intern_lang Symbols, so a lookup compares integers.
When a name does not resolve, or is defined twice, unresolved_name and
duplicate_definition turn that into a source-annotated diag_lang
Diagnostic.
§Quickstart
use symbol_lang::{duplicate_definition, unresolved_name, SymbolTable};
use intern_lang::Interner;
use diag_lang::Span;
let mut names = Interner::new();
let x = names.intern("x");
let y = names.intern("y");
// Bindings can be anything — here, the span where each name was defined.
let mut table: SymbolTable<Span> = SymbolTable::new();
table.define(x, Span::new(0, 1));
// Resolve a reference.
assert!(table.lookup(x).is_some());
assert!(table.lookup(y).is_none());
// Turn an unresolved reference into a diagnostic.
let diag = unresolved_name("y", Span::new(10, 11));
assert_eq!(diag.message(), "cannot find `y` in this scope");
// A duplicate definition links both sites.
if let Some(first) = table.lookup_local(x).copied() {
let _ = duplicate_definition("x", Span::new(20, 21), first);
}§Features
std(default) — the standard library; without it the crate isno_std(it always needsalloc). Forwards todiag-lang/stdandintern-lang/std.
§Stability
The public surface is being designed across the 0.x series and freezes at
1.0.0, after which it follows Semantic Versioning: no breaking changes before
2.0, additions arrive in minor releases, and the MSRV (Rust 1.85) only rises
in a minor. The frozen surface is catalogued in
docs/API.md.
Structs§
- Diagnostic
- One thing a compiler stage has to say about the source: a
Severity, a headline message, a primaryLabelpointing at the span it concerns, and optionally secondary labels for related locations and trailing note/help lines. - Span
- A half-open byte range
start..endinto a single source. - Symbol
- A small, copyable handle to a string held by an
Interner. - Symbol
Table - A lexically-scoped map from interned names to bindings.
Functions§
- duplicate_
definition - Builds the diagnostic for a name defined twice in the same scope.
- unresolved_
name - Builds the diagnostic for a name that is used but not bound in any scope.