use parser::{Expression, Statement};
use instructions::Instructions;
use memory::MemoryLayout;
use super::errors::Error;
use super::statements::expand;
use super::input::read_input;
pub fn if_condition(
instructions: &mut Instructions,
mem: &mut MemoryLayout,
condition: Expression,
body: Vec<Statement>,
) -> Result<(), Error> {
loop_condition(instructions, mem, &condition)?;
instructions.jump_forward_if_zero();
for stmt in body {
expand(instructions, mem, stmt)?;
}
loop_condition(instructions, mem, &condition)?;
instructions.jump_backward_unless_zero();
Ok(())
}
pub fn loop_condition(
instructions: &mut Instructions,
mem: &mut MemoryLayout,
condition: &Expression,
) -> Result<(), Error> {
let size = match condition {
&Expression::StringLiteral(_) => {
return Err(Error::LoopStringLiteralUnsupported {});
},
&Expression::Identifier(ref name) => {
let (_, size) = mem.get_cell_contents(name).ok_or_else(|| Error::UndeclaredIdentifier {name: name.clone()})?;
size
},
};
if size != 1 {
return Err(Error::ConditionSizeInvalid {
expected: 1,
actual: size,
});
}
Ok(())
}