Struct SymbolTable

Source
pub struct SymbolTable {
    scopes: Vec<Scope>,
}
Expand description

A symbol table for managing symbols during compilation

The symbol table stores all named entities (variables, types, functions) in the current scope. It provides functionality to define new symbols and look up existing ones by name. Each symbol is associated with its kind and type information.

§Example

use slang_shared::{SymbolTable, SymbolData};
use slang_types::TypeId;

let mut table = SymbolTable::new();
let type_id = TypeId::new(); // Example type ID

// Define a variable symbol
table.define("my_var".to_string(), SymbolData::Variable { is_mutable: true }, type_id).unwrap();

// Look up the symbol
let symbol = table.lookup("my_var").unwrap();
assert_eq!(symbol.name, "my_var");

Fields§

§scopes: Vec<Scope>

Stack of scopes, with the innermost scope at the end

Implementations§

Source§

impl SymbolTable

Source

pub fn new() -> Self

Creates a new symbol table with a global scope

§Returns

A new SymbolTable instance with an empty global scope

§Example
use slang_shared::SymbolTable;

let table = SymbolTable::new();
assert!(table.lookup("nonexistent").is_none());
Source

pub fn begin_scope(&mut self)

Begins a new scope by pushing it onto the scope stack

Used when entering a block, function, or other lexical scope.

Source

pub fn end_scope(&mut self)

Ends the current scope by popping it from the scope stack

Used when exiting a block, function, or other lexical scope. Will panic if attempting to end the global scope.

Source

pub fn define( &mut self, name: String, data: SymbolData, type_id: TypeId, ) -> Result<(), String>

Defines a new symbol in the current (innermost) scope

Attempts to add a new symbol with the given name, data, and type. If a symbol with the same name already exists in the current scope, returns an error with a descriptive message.

§Arguments
  • name - The name of the symbol to define
  • data - The specific data for this symbol kind
  • type_id - The type ID associated with this symbol
§Returns
  • Ok(()) if the symbol was successfully defined
  • Err(String) with an error message if the name is already taken
§Example
use slang_shared::{SymbolTable, SymbolData};
use slang_types::TypeId;

let mut table = SymbolTable::new();
let type_id = TypeId::new();

// Define a new variable
assert!(table.define("x".to_string(), SymbolData::Variable { is_mutable: true }, type_id.clone()).is_ok());

// Try to define the same name again - should fail
assert!(table.define("x".to_string(), SymbolData::Variable { is_mutable: false }, type_id).is_err());
Source

pub fn lookup(&self, name: &str) -> Option<&Symbol>

Looks up a symbol by name in all scopes, starting from innermost

Searches for a symbol with the given name starting from the innermost (current) scope and working outward. Returns a reference to the first matching symbol found.

§Arguments
  • name - The name of the symbol to look up
§Returns
  • Some(&Symbol) if a symbol with the given name exists
  • None if no symbol with the given name is found
§Example
use slang_shared::{SymbolTable, SymbolData};
use slang_types::TypeId;

let mut table = SymbolTable::new();
let type_id = TypeId::new();

table.define("my_function".to_string(), SymbolData::Function, type_id).unwrap();

let symbol = table.lookup("my_function").unwrap();
assert!(matches!(symbol.data, SymbolData::Function));
assert_eq!(symbol.name, "my_function");

assert!(table.lookup("nonexistent").is_none());

Trait Implementations§

Source§

impl Default for SymbolTable

Source§

fn default() -> SymbolTable

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