Add 'and' and 'or' operators to IR Generator
This commit is contained in:
parent
b3a8188dfe
commit
52d7ebde15
2 changed files with 69 additions and 3 deletions
|
@ -90,7 +90,7 @@ impl fmt::Display for IrInstructionType {
|
|||
IrInstructionType::CondJump(cond, then_dest, else_dest) => {
|
||||
format!("CondJump({cond}, {then_dest}, {else_dest})")
|
||||
}
|
||||
IrInstructionType::Label(name) => format!("Label({name})"),
|
||||
IrInstructionType::Label(name) => format!("\nLabel({name})"),
|
||||
};
|
||||
|
||||
write!(f, "{}", string)
|
||||
|
|
|
@ -126,8 +126,74 @@ fn visit_ast_node<'source>(
|
|||
}
|
||||
BinaryOp(left, op, right) => match *op {
|
||||
"=" => todo!(),
|
||||
"and" => todo!(),
|
||||
"or" => todo!(),
|
||||
"and" => {
|
||||
let l_right = add_label("and_right", right.loc, labels);
|
||||
let l_skip = add_label("and_skip", ast.loc, labels);
|
||||
let l_end = add_label("and_end", ast.loc, labels);
|
||||
|
||||
let left_var = visit_ast_node(left, types, symbols, instructions, labels);
|
||||
instructions.push(IrInstruction::new(
|
||||
left.loc,
|
||||
CondJump(
|
||||
left_var,
|
||||
Box::new(l_right.clone()),
|
||||
Box::new(l_skip.clone()),
|
||||
),
|
||||
));
|
||||
|
||||
instructions.push(l_right);
|
||||
let right_var = visit_ast_node(right, types, symbols, instructions, labels);
|
||||
let result_var = add_var(&ast.node_type, types);
|
||||
instructions.push(IrInstruction::new(
|
||||
right.loc,
|
||||
Copy(right_var, result_var.clone()),
|
||||
));
|
||||
instructions.push(IrInstruction::new(right.loc, Jump(Box::new(l_end.clone()))));
|
||||
|
||||
instructions.push(l_skip);
|
||||
instructions.push(IrInstruction::new(
|
||||
right.loc,
|
||||
LoadBoolConst(false, result_var.clone()),
|
||||
));
|
||||
instructions.push(IrInstruction::new(right.loc, Jump(Box::new(l_end.clone()))));
|
||||
|
||||
instructions.push(l_end);
|
||||
result_var
|
||||
}
|
||||
"or" => {
|
||||
let l_right = add_label("or_right", right.loc, labels);
|
||||
let l_skip = add_label("or_skip", ast.loc, labels);
|
||||
let l_end = add_label("or_end", ast.loc, labels);
|
||||
|
||||
let left_var = visit_ast_node(left, types, symbols, instructions, labels);
|
||||
instructions.push(IrInstruction::new(
|
||||
left.loc,
|
||||
CondJump(
|
||||
left_var,
|
||||
Box::new(l_skip.clone()),
|
||||
Box::new(l_right.clone()),
|
||||
),
|
||||
));
|
||||
|
||||
instructions.push(l_right);
|
||||
let right_var = visit_ast_node(right, types, symbols, instructions, labels);
|
||||
let result_var = add_var(&ast.node_type, types);
|
||||
instructions.push(IrInstruction::new(
|
||||
right.loc,
|
||||
Copy(right_var, result_var.clone()),
|
||||
));
|
||||
instructions.push(IrInstruction::new(right.loc, Jump(Box::new(l_end.clone()))));
|
||||
|
||||
instructions.push(l_skip);
|
||||
instructions.push(IrInstruction::new(
|
||||
right.loc,
|
||||
LoadBoolConst(true, result_var.clone()),
|
||||
));
|
||||
instructions.push(IrInstruction::new(right.loc, Jump(Box::new(l_end.clone()))));
|
||||
|
||||
instructions.push(l_end);
|
||||
result_var
|
||||
}
|
||||
_ => {
|
||||
let op_var = symbols.get(op).clone();
|
||||
let left_var = visit_ast_node(left, types, symbols, instructions, labels);
|
||||
|
|
Reference in a new issue