1
0
Fork 0

Add 'and' and 'or' operators to IR Generator

This commit is contained in:
Vili Sinervä 2025-02-06 15:11:38 +02:00
parent b3a8188dfe
commit 52d7ebde15
No known key found for this signature in database
GPG key ID: DF8FEAF54EFAC996
2 changed files with 69 additions and 3 deletions

View file

@ -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)

View file

@ -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);