use leo_ast::*;
use crate::unroller::Unroller;
use crate::{VariableSymbol, VariableType};
impl StatementReconstructor for Unroller<'_> {
fn reconstruct_block(&mut self, input: Block) -> (Block, Self::AdditionalOutput) {
let scope_index = self.current_scope_index();
let previous_scope_index = self.enter_scope(scope_index);
let block = Block {
statements: input
.statements
.into_iter()
.map(|s| self.reconstruct_statement(s).0)
.collect(),
span: input.span,
};
self.exit_scope(previous_scope_index);
(block, Default::default())
}
fn reconstruct_definition(&mut self, input: DefinitionStatement) -> (Statement, Self::AdditionalOutput) {
if self.is_unrolling {
let declaration = if input.declaration_type == DeclarationType::Const {
VariableType::Const
} else {
VariableType::Mut
};
if let Err(err) = self.symbol_table.borrow_mut().insert_variable(
input.variable_name.name,
VariableSymbol {
type_: input.type_.clone(),
span: input.span(),
declaration,
},
) {
self.handler.emit_err(err);
}
}
(Statement::Definition(input), Default::default())
}
fn reconstruct_iteration(&mut self, input: IterationStatement) -> (Statement, Self::AdditionalOutput) {
match (
input.start_value.clone().into_inner(),
input.stop_value.clone().into_inner(),
) {
(Some(start), Some(stop)) => match (Type::from(&start), Type::from(&stop)) {
(Type::Integer(IntegerType::I8), Type::Integer(IntegerType::I8))
| (Type::Integer(IntegerType::I16), Type::Integer(IntegerType::I16))
| (Type::Integer(IntegerType::I32), Type::Integer(IntegerType::I32))
| (Type::Integer(IntegerType::I64), Type::Integer(IntegerType::I64))
| (Type::Integer(IntegerType::I128), Type::Integer(IntegerType::I128)) => (
self.unroll_iteration_statement::<i128>(input, start, stop),
Default::default(),
),
(Type::Integer(IntegerType::U8), Type::Integer(IntegerType::U8))
| (Type::Integer(IntegerType::U16), Type::Integer(IntegerType::U16))
| (Type::Integer(IntegerType::U32), Type::Integer(IntegerType::U32))
| (Type::Integer(IntegerType::U64), Type::Integer(IntegerType::U64))
| (Type::Integer(IntegerType::U128), Type::Integer(IntegerType::U128)) => (
self.unroll_iteration_statement::<u128>(input, start, stop),
Default::default(),
),
_ => unreachable!("Type checking ensures that `start` and `stop` have the same type."),
},
_ => (Statement::Iteration(Box::from(input)), Default::default()),
}
}
}