use crate::{Assigner, RenameTable, SymbolTable, TypeTable};
use leo_ast::{Expression, Identifier, Node, NodeBuilder, Statement};
use leo_span::Symbol;
pub struct StaticSingleAssigner<'a> {
pub(crate) node_builder: &'a NodeBuilder,
pub(crate) symbol_table: &'a SymbolTable,
pub(crate) type_table: &'a TypeTable,
pub(crate) rename_table: RenameTable,
pub(crate) assigner: &'a Assigner,
pub(crate) program: Option<Symbol>,
}
impl<'a> StaticSingleAssigner<'a> {
pub(crate) fn new(
node_builder: &'a NodeBuilder,
symbol_table: &'a SymbolTable,
type_table: &'a TypeTable,
assigner: &'a Assigner,
) -> Self {
Self { node_builder, symbol_table, type_table, rename_table: RenameTable::new(None), assigner, program: None }
}
pub(crate) fn push(&mut self) {
let parent_table = core::mem::take(&mut self.rename_table);
self.rename_table = RenameTable::new(Some(Box::from(parent_table)));
}
pub(crate) fn pop(&mut self) -> RenameTable {
let parent = self.rename_table.parent.clone().unwrap_or_default();
core::mem::replace(&mut self.rename_table, *parent)
}
pub(crate) fn rename_identifier(&mut self, mut identifier: Identifier) -> Identifier {
self.rename_table.update(identifier.name, identifier.name, identifier.id);
let new_name = self.assigner.unique_symbol(identifier.name, "$#");
self.rename_table.update(identifier.name, new_name, identifier.id);
identifier.name = new_name;
identifier
}
pub(crate) fn simple_definition(&mut self, identifier: Identifier, rhs: Expression) -> Statement {
let type_ = match self.type_table.get(&rhs.id()) {
Some(type_) => type_,
None => unreachable!("Type checking guarantees that all expressions have a type."),
};
self.type_table.insert(identifier.id(), type_);
self.rename_table.update(identifier.name, identifier.name, identifier.id);
self.assigner.simple_definition(identifier, rhs, self.node_builder.next_id())
}
pub(crate) fn unique_simple_definition(&mut self, expr: Expression) -> (Identifier, Statement) {
let name = self.assigner.unique_symbol("$var", "$");
let place = Identifier { name, span: Default::default(), id: self.node_builder.next_id() };
let statement = self.simple_definition(place, expr);
(place, statement)
}
}