pub struct SymbolsTable { /* private fields */ }Expand description
Compile-time symbols table for tracking variable bindings.
Maps variable names to storage indices, enabling the compiler to resolve identifiers to global, local, free, and function-scoped storage slots. Supports nested scopes via an optional outer table reference, allowing local bindings to shadow globals and enabling scope-chain resolution during identifier lookup.
When resolving a symbol that lives in a non-global, non-builtin enclosing scope, the table automatically promotes it to a free variable, recording the original symbol for the compiler to emit the appropriate load instructions at closure-creation time.
Symbols can be masked to temporarily hide them from resolution without removing their storage indices. This supports multi-module compilation where a shared compiler must prevent cross-module symbol leaks while preserving global index assignments.
Implementations§
Source§impl SymbolsTable
impl SymbolsTable
Sourcepub fn new_enclosed(outer: SymbolsTable) -> Self
pub fn new_enclosed(outer: SymbolsTable) -> Self
Creates a new symbols table enclosed by the given outer table.
Symbols defined in the enclosed table receive SymbolScope::Local,
while resolution walks up to the outer table for undefined names.
Sourcepub fn max_definitions(&self) -> usize
pub fn max_definitions(&self) -> usize
Returns the number of local slots the VM must allocate for this scope.
This is the high-water mark of simultaneously live locals, accounting for slot reuse across non-overlapping block scopes.
Sourcepub fn push_block_scope(&mut self)
pub fn push_block_scope(&mut self)
Enters a new block scope, saving the current definition count.
Variables defined after this call are tracked so they can be
removed when pop_block_scope is called, enabling lexical
block scoping within a single function.
Sourcepub fn pop_block_scope(&mut self)
pub fn pop_block_scope(&mut self)
Exits the current block scope, removing locally defined symbols.
All symbols defined since the matching push_block_scope are
removed from the store and num_definitions is restored,
allowing the local slot indices to be reused by subsequent blocks.
Sourcepub fn define_symbol(&mut self, name: &str, mutable: bool) -> Result<&Symbol>
pub fn define_symbol(&mut self, name: &str, mutable: bool) -> Result<&Symbol>
Defines a symbol, assigning it the next available index.
If a symbol with the same name already exists at the same scope
level (Global or Local), the existing index is reused. This
enables idiomatic rebinding inside loops (let x = x + 1;)
without allocating a new storage slot on each iteration.
The symbol’s scope is determined by whether this table has an outer (enclosing) table: global scope if no outer, local scope otherwise.
§Errors
Returns CompileErrorKind::SymbolsTableOverflow if the maximum number
of global bindings has been reached (only checked for global scope).
Sourcepub fn define_builtin(&mut self, index: usize, name: &str) -> &Symbol
pub fn define_builtin(&mut self, index: usize, name: &str) -> &Symbol
Defines a built-in function symbol with a fixed index.
Built-in symbols are stored in the table but do not increment
num_definitions, as they occupy no global or local storage slots.
They are resolved by index at runtime via OpGetBuiltin.
Sourcepub fn define_function_name(&mut self, name: &str)
pub fn define_function_name(&mut self, name: &str)
Defines the enclosing function’s own name for recursive self-reference.
The symbol is stored at index 0 with SymbolScope::Function but does
not increment num_definitions, since it occupies no local slot.
At runtime, the VM resolves this via OpCurrentClosure.
Sourcepub fn resolve_symbol(&mut self, name: &str) -> Option<Symbol>
pub fn resolve_symbol(&mut self, name: &str) -> Option<Symbol>
Resolves a symbol by name, walking up the scope chain.
When a symbol is found in an enclosing (non-global, non-builtin) scope, it is automatically promoted to a free variable in the current scope. This records the capture chain so the compiler can emit the correct load instructions when creating closures.
Sourcepub fn free_vars(&self) -> &[Symbol]
pub fn free_vars(&self) -> &[Symbol]
Returns the free variables captured by this scope.
The returned slice is ordered by free variable index. The compiler uses this to emit load instructions for each captured variable before creating the closure.
Sourcepub fn take_outer(self) -> Option<SymbolsTable>
pub fn take_outer(self) -> Option<SymbolsTable>
Extracts the outer table from this enclosed table.
Returns None if this is a top-level (global) table.
Sourcepub fn global_symbol_names(&self) -> Vec<String>
pub fn global_symbol_names(&self) -> Vec<String>
Returns the names of all unmasked, globally-scoped symbols.
Useful for snapshotting the global namespace before compiling a module, so that newly-defined globals can be identified afterward.
Sourcepub fn mask_symbol(&mut self, name: &str)
pub fn mask_symbol(&mut self, name: &str)
Masks a symbol, hiding it from resolution without removing its storage index.
Masked symbols retain their global indices so that re-defining them (via import injection) reuses the same slot. This prevents cross-module symbol leaks in shared-compiler pipelines while keeping the bytecode’s index references valid.
Trait Implementations§
Source§impl Clone for SymbolsTable
impl Clone for SymbolsTable
Source§fn clone(&self) -> SymbolsTable
fn clone(&self) -> SymbolsTable
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more