deimos-lang/dmc-lib/src/ir/ir_binary_operation.rs
2026-03-15 13:16:21 -05:00

89 lines
2.5 KiB
Rust

use crate::constants_table::ConstantsTable;
use crate::ir::assemble::InstructionsBuilder;
use crate::ir::ir_expression::IrExpression;
use crate::ir::ir_variable::IrVrVariableDescriptor;
use crate::ir::register_allocation::VrUser;
use dvm_lib::instruction::{Instruction, Location};
use std::collections::HashSet;
use std::fmt::{Display, Formatter};
pub enum IrBinaryOperator {
Multiply,
Divide,
Add,
Subtract,
}
pub struct IrBinaryOperation {
left: Box<IrExpression>,
right: Box<IrExpression>,
op: IrBinaryOperator,
}
impl IrBinaryOperation {
pub fn new(left: IrExpression, right: IrExpression, op: IrBinaryOperator) -> Self {
Self {
left: left.into(),
right: right.into(),
op,
}
}
pub fn assemble_assign(
&self,
builder: &mut InstructionsBuilder,
constants_table: &mut ConstantsTable,
destination: Location,
) {
let instruction = match &self.op {
IrBinaryOperator::Multiply => Instruction::Multiply(
self.left.multiply_operand(),
self.right.multiply_operand(),
destination,
),
IrBinaryOperator::Divide => {
todo!()
}
IrBinaryOperator::Add => Instruction::Add(
self.left.add_operand(constants_table),
self.right.add_operand(constants_table),
destination,
),
IrBinaryOperator::Subtract => Instruction::Subtract(
self.left.subtract_operand(),
self.right.subtract_operand(),
destination,
),
};
builder.push(instruction);
}
}
impl Display for IrBinaryOperation {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match &self.op {
IrBinaryOperator::Multiply => {
write!(f, "{} * {}", self.left, self.right)
}
IrBinaryOperator::Divide => {
write!(f, "{} / {}", self.left, self.right)
}
IrBinaryOperator::Add => {
write!(f, "{} + {}", self.left, self.right)
}
IrBinaryOperator::Subtract => {
write!(f, "{} - {}", self.left, self.right)
}
}
}
}
impl VrUser for IrBinaryOperation {
fn vr_uses(&self) -> HashSet<IrVrVariableDescriptor> {
[self.left.as_ref(), self.right.as_ref()]
.iter()
.flat_map(|e| e.vr_uses())
.collect()
}
}