use crate::asm_generation::{convert_expression_to_asm, AsmNamespace, RegisterSequencer};
use crate::asm_lang::{ConstantRegister, Op, VirtualRegister};
use crate::error::*;
use crate::semantic_analysis::TypedExpression;
use crate::CompileResult;
pub(crate) fn convert_if_exp_to_asm<'sc>(
condition: &TypedExpression<'sc>,
then: &TypedExpression<'sc>,
r#else: &Option<Box<TypedExpression<'sc>>>,
return_register: &VirtualRegister,
namespace: &mut AsmNamespace<'sc>,
register_sequencer: &mut RegisterSequencer,
) -> CompileResult<'sc, Vec<Op<'sc>>> {
let mut warnings = vec![];
let mut errors = vec![];
let mut asm_buf = vec![];
let else_label = register_sequencer.get_label();
let after_else_label = register_sequencer.get_label();
let condition_result = register_sequencer.next();
let mut condition = check!(
convert_expression_to_asm(condition, namespace, &condition_result, register_sequencer),
return err(warnings, errors),
warnings,
errors
);
asm_buf.push(Op::new_comment("begin if expression"));
asm_buf.append(&mut condition);
asm_buf.push(Op::jump_if_not_equal(
condition_result.clone(),
VirtualRegister::Constant(ConstantRegister::One),
if r#else.is_some() {
else_label.clone()
} else {
after_else_label.clone()
},
));
let then_branch_result = register_sequencer.next();
let mut then_branch = check!(
convert_expression_to_asm(then, namespace, &then_branch_result, register_sequencer),
return err(warnings, errors),
warnings,
errors
);
asm_buf.append(&mut then_branch);
asm_buf.push(Op::register_move(
return_register.clone(),
then_branch_result,
then.clone().span,
));
asm_buf.push(Op::jump_to_label_comment(
after_else_label.clone(),
"end of then branch",
));
if let Some(r#else) = r#else {
asm_buf.push(Op::jump_label_comment(
else_label,
r#else.span.clone(),
"beginning of else branch",
));
let else_branch_result = register_sequencer.next();
let mut else_branch = check!(
convert_expression_to_asm(r#else, namespace, &else_branch_result, register_sequencer),
return err(warnings, errors),
warnings,
errors
);
asm_buf.append(&mut else_branch);
asm_buf.push(Op::register_move(
return_register.clone(),
else_branch_result,
r#else.clone().span,
));
}
asm_buf.push(Op::unowned_jump_label_comment(
after_else_label,
"End of if exp",
));
ok(asm_buf, warnings, errors)
}