Skip to main content

SymbolsTable

Struct SymbolsTable 

Source
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

Source

pub fn new() -> Self

Creates a new empty symbols table at global scope.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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).

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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

Source§

fn clone(&self) -> SymbolsTable

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for SymbolsTable

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for SymbolsTable

Source§

fn default() -> SymbolsTable

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.