Skip to main content

Crate symbol_lang

Crate symbol_lang 

Source
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 is no_std (it always needs alloc). Forwards to diag-lang/std and intern-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 primary Label pointing at the span it concerns, and optionally secondary labels for related locations and trailing note/help lines.
Span
A half-open byte range start..end into a single source.
Symbol
A small, copyable handle to a string held by an Interner.
SymbolTable
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.