use crate::{CompilerState, Pass};
use leo_ast::*;
use leo_errors::Result;
use leo_span::{Symbol, sym};
pub struct Disambiguate;
impl Pass for Disambiguate {
type Input = ();
type Output = ();
const NAME: &str = "Disambiguate";
fn do_pass(_input: Self::Input, state: &mut crate::CompilerState) -> Result<Self::Output> {
let mut ast = std::mem::take(&mut state.ast);
let mut visitor = DisambiguateVisitor { state };
ast.ast = visitor.reconstruct_program(ast.ast);
visitor.state.handler.last_err()?;
visitor.state.ast = ast;
Ok(())
}
}
pub struct DisambiguateVisitor<'state> {
pub state: &'state mut CompilerState,
}
impl ProgramReconstructor for DisambiguateVisitor<'_> {}
impl AstReconstructor for DisambiguateVisitor<'_> {
type AdditionalInput = ();
type AdditionalOutput = ();
fn reconstruct_intrinsic(
&mut self,
mut input: IntrinsicExpression,
_additional: &Self::AdditionalInput,
) -> (Expression, Self::AdditionalOutput) {
input.arguments = input.arguments.into_iter().map(|arg| self.reconstruct_expression(arg, &()).0).collect();
if input.name == Symbol::intern("__unresolved_get") {
match self.state.type_table.get(&input.arguments[0].id()) {
Some(Type::Vector(..)) => {
input.name = sym::_vector_get;
}
Some(Type::Mapping(..)) => {
input.name = sym::_mapping_get;
}
_ => {
panic!("type checking should guarantee that no other type is expected here.")
}
}
} else if input.name == Symbol::intern("__unresolved_set") {
match self.state.type_table.get(&input.arguments[0].id()) {
Some(Type::Vector(..)) => {
input.name = sym::_vector_set;
}
Some(Type::Mapping(..)) => {
input.name = sym::_mapping_set;
}
_ => {
panic!("type checking should guarantee that no other type is expected here.")
}
}
}
(input.into(), ())
}
}