Struct naga::front::SymbolTable
source · pub struct SymbolTable<Name, Var> { /* private fields */ }
Expand description
Structure responsible for managing variable lookups and keeping track of lexical scopes
The symbol table is generic over the variable representation and its name to allow larger flexibility on the frontends on how they might represent them.
use naga::front::SymbolTable;
// Create a new symbol table with `u32`s representing the variable
let mut symbol_table: SymbolTable<&str, u32> = SymbolTable::default();
// Add two variables named `var1` and `var2` with 0 and 2 respectively
symbol_table.add("var1", 0);
symbol_table.add("var2", 2);
// Check that `var1` exists and is `0`
assert_eq!(symbol_table.lookup("var1"), Some(&0));
// Push a new scope and add a variable to it named `var1` shadowing the
// variable of our previous scope
symbol_table.push_scope();
symbol_table.add("var1", 1);
// Check that `var1` now points to the new value of `1` and `var2` still
// exists with its value of `2`
assert_eq!(symbol_table.lookup("var1"), Some(&1));
assert_eq!(symbol_table.lookup("var2"), Some(&2));
// Pop the scope
symbol_table.pop_scope();
// Check that `var1` now refers to our initial variable with value `0`
assert_eq!(symbol_table.lookup("var1"), Some(&0));
Scopes are ordered as a LIFO stack so a variable defined in a later scope
with the same name as another variable defined in a earlier scope will take
precedence in the lookup. Scopes can be added with push_scope
and
removed with pop_scope
.
A root scope is added when the symbol table is created and must always be present. Trying to pop it will result in a panic.
Variables can be added with add
and looked up with lookup
. Adding a
variable will do so in the currently active scope and as mentioned
previously a lookup will search from the current scope to the root scope.
Implementations§
source§impl<Name, Var> SymbolTable<Name, Var>
impl<Name, Var> SymbolTable<Name, Var>
sourcepub fn push_scope(&mut self)
pub fn push_scope(&mut self)
Adds a new lexical scope.
All variables declared after this point will be added to this scope
until another scope is pushed or pop_scope
is called, causing this
scope to be removed along with all variables added to it.
source§impl<Name, Var> SymbolTable<Name, Var>
impl<Name, Var> SymbolTable<Name, Var>
sourcepub fn lookup<Q>(&self, name: &Q) -> Option<&Var>
pub fn lookup<Q>(&self, name: &Q) -> Option<&Var>
Perform a lookup for a variable named name
.
As stated in the struct level documentation the lookup will proceed from
the current scope to the root scope, returning Some
when a variable is
found or None
if there doesn’t exist a variable with name
in any
scope.
sourcepub fn add(&mut self, name: Name, var: Var) -> Option<Var>
pub fn add(&mut self, name: Name, var: Var) -> Option<Var>
Adds a new variable to the current scope.
Returns the previous variable with the same name in this scope if it exists, so that the frontend might handle it in case variable shadowing is disallowed.
sourcepub fn add_root(&mut self, name: Name, var: Var) -> Option<Var>
pub fn add_root(&mut self, name: Name, var: Var) -> Option<Var>
Adds a new variable to the root scope.
This is used in GLSL for builtins which aren’t known in advance and only when used for the first time, so there must be a way to add those declarations to the root unconditionally from the current scope.
Returns the previous variable with the same name in the root scope if it exists, so that the frontend might handle it in case variable shadowing is disallowed.