use crate::{CompilerState, ConstPropagation, Pass, Unrolling};
use leo_errors::{CompilerError, Result};
pub struct ConstPropagationAndUnrolling;
impl Pass for ConstPropagationAndUnrolling {
type Input = ();
type Output = ();
const NAME: &str = "ConstPropagationAndUnrolling";
fn do_pass(_input: Self::Input, state: &mut CompilerState) -> Result<Self::Output> {
const LARGE_LOOP_BOUND: usize = 1024usize;
for _ in 0..LARGE_LOOP_BOUND {
let loop_unroll_output = Unrolling::do_pass((), state)?;
let const_prop_output = ConstPropagation::do_pass((), state)?;
if !const_prop_output.changed && !loop_unroll_output.loop_unrolled {
if let Some(not_evaluated_span) = const_prop_output.const_not_evaluated {
return Err(CompilerError::const_not_evaluated(not_evaluated_span).into());
}
if let Some(not_evaluated_span) = const_prop_output.array_index_not_evaluated {
return Err(CompilerError::array_index_not_evaluated(not_evaluated_span).into());
}
if let Some(not_unrolled_span) = loop_unroll_output.loop_not_unrolled {
return Err(CompilerError::loop_bounds_not_evaluated(not_unrolled_span).into());
}
return Ok(());
}
}
Err(CompilerError::const_prop_unroll_many_loops(LARGE_LOOP_BOUND, Default::default()).into())
}
}