From f9373a687ffe40ff8a8e0246cfad4df3bdc48603 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Sun, 15 Mar 2026 12:55:00 -0500 Subject: [PATCH] Refactor to use IrBinaryOperation. --- dmc-lib/src/ast/binary_expression.rs | 18 ++--- dmc-lib/src/ast/negative_expression.rs | 16 ++-- dmc-lib/src/ir/ir_add.rs | 75 ----------------- dmc-lib/src/ir/ir_assign.rs | 13 +-- dmc-lib/src/ir/ir_binary_operation.rs | 107 +++++++++++++++++++++++++ dmc-lib/src/ir/ir_multiply.rs | 67 ---------------- dmc-lib/src/ir/ir_operation.rs | 82 +++---------------- dmc-lib/src/ir/ir_subtract.rs | 63 --------------- dmc-lib/src/ir/mod.rs | 4 +- 9 files changed, 140 insertions(+), 305 deletions(-) delete mode 100644 dmc-lib/src/ir/ir_add.rs create mode 100644 dmc-lib/src/ir/ir_binary_operation.rs delete mode 100644 dmc-lib/src/ir/ir_multiply.rs delete mode 100644 dmc-lib/src/ir/ir_subtract.rs diff --git a/dmc-lib/src/ast/binary_expression.rs b/dmc-lib/src/ast/binary_expression.rs index f0c6627..7dbd881 100644 --- a/dmc-lib/src/ast/binary_expression.rs +++ b/dmc-lib/src/ast/binary_expression.rs @@ -2,12 +2,11 @@ use crate::ast::expression::Expression; use crate::ast::ir_builder::IrBuilder; use crate::diagnostic::Diagnostic; use crate::error_codes::BINARY_INCOMPATIBLE_TYPES; -use crate::ir::ir_add::IrAdd; use crate::ir::ir_assign::IrAssign; +use crate::ir::ir_binary_operation::{IrBinaryOperation, IrBinaryOperator}; use crate::ir::ir_expression::IrExpression; use crate::ir::ir_operation::IrOperation; use crate::ir::ir_statement::IrStatement; -use crate::ir::ir_subtract::IrSubtract; use crate::ir::ir_variable::IrVariable; use crate::source_range::SourceRange; use crate::symbol_table::SymbolTable; @@ -179,16 +178,17 @@ impl BinaryExpression { .rhs .to_ir_expression(builder, symbol_table) .expect("Attempt to use a non-value expression in binary expression."); - match self.op { + let ir_binary_operation = match self.op { BinaryOperation::Multiply => { - todo!() + IrBinaryOperation::new(lhs, rhs, IrBinaryOperator::Multiply) } - BinaryOperation::Divide => { - todo!() + BinaryOperation::Divide => IrBinaryOperation::new(lhs, rhs, IrBinaryOperator::Divide), + BinaryOperation::Add => IrBinaryOperation::new(lhs, rhs, IrBinaryOperator::Add), + BinaryOperation::Subtract => { + IrBinaryOperation::new(lhs, rhs, IrBinaryOperator::Subtract) } - BinaryOperation::Add => IrOperation::Add(IrAdd::new(lhs, rhs)), - BinaryOperation::Subtract => IrOperation::Subtract(IrSubtract::new(lhs, rhs)), - } + }; + IrOperation::Binary(ir_binary_operation) } pub fn to_ir_expression( diff --git a/dmc-lib/src/ast/negative_expression.rs b/dmc-lib/src/ast/negative_expression.rs index f84c4e1..d3de26a 100644 --- a/dmc-lib/src/ast/negative_expression.rs +++ b/dmc-lib/src/ast/negative_expression.rs @@ -2,8 +2,8 @@ use crate::ast::expression::Expression; use crate::ast::ir_builder::IrBuilder; use crate::diagnostic::Diagnostic; use crate::ir::ir_assign::IrAssign; +use crate::ir::ir_binary_operation::{IrBinaryOperation, IrBinaryOperator}; use crate::ir::ir_expression::IrExpression; -use crate::ir::ir_multiply::IrMultiply; use crate::ir::ir_operation::IrOperation; use crate::ir::ir_statement::IrStatement; use crate::ir::ir_variable::IrVariable; @@ -87,8 +87,11 @@ impl NegativeExpression { _ => panic!("Trying to multiply with a non-integer/double"), }; - let operation = - IrOperation::Multiply(IrMultiply::new(IrExpression::Parameter(parameter), rhs)); + let operation = IrOperation::Binary(IrBinaryOperation::new( + IrExpression::Parameter(parameter), + rhs, + IrBinaryOperator::Multiply, + )); let assign = IrAssign::new(destination.clone(), operation); builder @@ -110,8 +113,11 @@ impl NegativeExpression { _ => panic!("Trying to multiply with a non-integer/double"), }; - let operation = - IrOperation::Multiply(IrMultiply::new(IrExpression::Variable(variable), rhs)); + let operation = IrOperation::Binary(IrBinaryOperation::new( + IrExpression::Variable(variable), + rhs, + IrBinaryOperator::Multiply, + )); let assign = IrAssign::new(destination.clone(), operation); builder diff --git a/dmc-lib/src/ir/ir_add.rs b/dmc-lib/src/ir/ir_add.rs deleted file mode 100644 index d614971..0000000 --- a/dmc-lib/src/ir/ir_add.rs +++ /dev/null @@ -1,75 +0,0 @@ -use crate::constants_table::ConstantsTable; -use crate::ir::ir_expression::IrExpression; -use crate::ir::ir_variable::IrVrVariableDescriptor; -use crate::ir::register_allocation::{OffsetCounter, VrUser}; -use dvm_lib::instruction::AddOperand; -use std::collections::{HashMap, HashSet}; -use std::fmt::{Display, Formatter}; - -pub struct IrAdd { - left: Box, - right: Box, -} - -impl IrAdd { - pub fn new(left: IrExpression, right: IrExpression) -> Self { - Self { - left: left.into(), - right: right.into(), - } - } - - pub fn left(&self) -> &IrExpression { - &self.left - } - - pub fn right(&self) -> &IrExpression { - &self.right - } - - pub fn operand_pair(&self, constants_table: &mut ConstantsTable) -> (AddOperand, AddOperand) { - ( - self.left.add_operand(constants_table), - self.right.add_operand(constants_table), - ) - } -} - -impl Display for IrAdd { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{} + {}", self.left, self.right) - } -} - -impl VrUser for IrAdd { - fn vr_definitions(&self) -> HashSet { - [self.left.as_ref(), self.right.as_ref()] - .iter() - .flat_map(|e| e.vr_definitions()) - .collect() - } - - fn vr_uses(&self) -> HashSet { - [self.left.as_ref(), self.right.as_ref()] - .iter() - .flat_map(|e| e.vr_uses()) - .collect() - } - - fn propagate_spills(&mut self, spills: &HashSet) { - self.left.propagate_spills(spills); - self.right.propagate_spills(spills); - } - - fn propagate_register_assignments( - &mut self, - assignments: &HashMap, - ) { - self.left.propagate_register_assignments(assignments); - self.right.propagate_register_assignments(assignments); - } - - fn propagate_stack_offsets(&mut self, _counter: &mut OffsetCounter) { - // no-op, no definitions here - } -} diff --git a/dmc-lib/src/ir/ir_assign.rs b/dmc-lib/src/ir/ir_assign.rs index 195ef82..0c0a126 100644 --- a/dmc-lib/src/ir/ir_assign.rs +++ b/dmc-lib/src/ir/ir_assign.rs @@ -116,17 +116,8 @@ impl Assemble for IrAssign { let move_operand = ir_expression.move_operand(constants_table); builder.push(Instruction::Move(move_operand, destination)); } - IrOperation::Add(ir_add) => { - let (left, right) = ir_add.operand_pair(constants_table); - builder.push(Instruction::Add(left, right, destination)); - } - IrOperation::Subtract(ir_subtract) => { - let (left, right) = ir_subtract.operand_pair(); - builder.push(Instruction::Subtract(left, right, destination)); - } - IrOperation::Multiply(ir_multiply) => { - let (left, right) = ir_multiply.operand_pair(); - builder.push(Instruction::Multiply(left, right, destination)); + IrOperation::Binary(ir_binary_operation) => { + ir_binary_operation.assemble_assign(builder, constants_table, destination); } IrOperation::Call(ir_call) => { ir_call.assemble(builder, constants_table); diff --git a/dmc-lib/src/ir/ir_binary_operation.rs b/dmc-lib/src/ir/ir_binary_operation.rs new file mode 100644 index 0000000..f053f60 --- /dev/null +++ b/dmc-lib/src/ir/ir_binary_operation.rs @@ -0,0 +1,107 @@ +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::{OffsetCounter, VrUser}; +use dvm_lib::instruction::{Instruction, Location}; +use std::collections::{HashMap, HashSet}; +use std::fmt::{Display, Formatter}; + +pub enum IrBinaryOperator { + Multiply, + Divide, + Add, + Subtract, +} + +pub struct IrBinaryOperation { + left: Box, + right: Box, + 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_definitions(&self) -> HashSet { + todo!() + } + + fn vr_uses(&self) -> HashSet { + [self.left.as_ref(), self.right.as_ref()] + .iter() + .flat_map(|e| e.vr_uses()) + .collect() + } + + fn propagate_spills(&mut self, spills: &HashSet) { + todo!() + } + + fn propagate_register_assignments( + &mut self, + assignments: &HashMap, + ) { + todo!() + } + + fn propagate_stack_offsets(&mut self, counter: &mut OffsetCounter) { + todo!() + } +} diff --git a/dmc-lib/src/ir/ir_multiply.rs b/dmc-lib/src/ir/ir_multiply.rs deleted file mode 100644 index 945e3f6..0000000 --- a/dmc-lib/src/ir/ir_multiply.rs +++ /dev/null @@ -1,67 +0,0 @@ -use crate::ir::ir_expression::IrExpression; -use crate::ir::ir_variable::IrVrVariableDescriptor; -use crate::ir::register_allocation::{OffsetCounter, VrUser}; -use dvm_lib::instruction::MultiplyOperand; -use std::collections::{HashMap, HashSet}; -use std::fmt::{Display, Formatter}; - -pub struct IrMultiply { - left: Box, - right: Box, -} - -impl IrMultiply { - pub fn new(left: IrExpression, right: IrExpression) -> Self { - Self { - left: left.into(), - right: right.into(), - } - } - - pub fn operand_pair(&self) -> (MultiplyOperand, MultiplyOperand) { - (self.left.multiply_operand(), self.right.multiply_operand()) - } -} - -impl Display for IrMultiply { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{} * {}", self.left, self.right) - } -} - -impl VrUser for IrMultiply { - fn vr_definitions(&self) -> HashSet { - [&self.left, &self.right] - .iter() - .flat_map(|ir_expression| ir_expression.vr_definitions()) - .collect() - } - - fn vr_uses(&self) -> HashSet { - [&self.left, &self.right] - .iter() - .flat_map(|ir_expression| ir_expression.vr_uses()) - .collect() - } - - fn propagate_spills(&mut self, spills: &HashSet) { - [&mut self.left, &mut self.right] - .iter_mut() - .for_each(|ir_expression| ir_expression.propagate_spills(spills)); - } - - fn propagate_register_assignments( - &mut self, - assignments: &HashMap, - ) { - [&mut self.left, &mut self.right] - .iter_mut() - .for_each(|ir_expression| ir_expression.propagate_register_assignments(assignments)); - } - - fn propagate_stack_offsets(&mut self, counter: &mut OffsetCounter) { - [&mut self.left, &mut self.right] - .iter_mut() - .for_each(|ir_expression| ir_expression.propagate_stack_offsets(counter)); - } -} diff --git a/dmc-lib/src/ir/ir_operation.rs b/dmc-lib/src/ir/ir_operation.rs index 919cefc..0d3ca3e 100644 --- a/dmc-lib/src/ir/ir_operation.rs +++ b/dmc-lib/src/ir/ir_operation.rs @@ -1,12 +1,10 @@ -use crate::ir::ir_add::IrAdd; use crate::ir::ir_allocate::IrAllocate; +use crate::ir::ir_binary_operation::IrBinaryOperation; use crate::ir::ir_call::IrCall; use crate::ir::ir_expression::IrExpression; use crate::ir::ir_get_field_ref::IrGetFieldRef; use crate::ir::ir_get_field_ref_mut::IrGetFieldRefMut; -use crate::ir::ir_multiply::IrMultiply; use crate::ir::ir_read_field::IrReadField; -use crate::ir::ir_subtract::IrSubtract; use crate::ir::ir_variable::IrVrVariableDescriptor; use crate::ir::register_allocation::{OffsetCounter, VrUser}; use std::collections::{HashMap, HashSet}; @@ -17,9 +15,7 @@ pub enum IrOperation { GetFieldRefMut(IrGetFieldRefMut), ReadField(IrReadField), Load(IrExpression), - Add(IrAdd), - Subtract(IrSubtract), - Multiply(IrMultiply), + Binary(IrBinaryOperation), Call(IrCall), Allocate(IrAllocate), } @@ -39,14 +35,8 @@ impl Display for IrOperation { IrOperation::Load(ir_expression) => { write!(f, "{}", ir_expression) } - IrOperation::Add(ir_add) => { - write!(f, "{}", ir_add) - } - IrOperation::Subtract(ir_subtract) => { - write!(f, "{}", ir_subtract) - } - IrOperation::Multiply(ir_multiply) => { - write!(f, "{}", ir_multiply) + IrOperation::Binary(ir_binary_operation) => { + write!(f, "{}", ir_binary_operation) } IrOperation::Call(ir_call) => { write!(f, "{}", ir_call) @@ -60,17 +50,7 @@ impl Display for IrOperation { impl VrUser for IrOperation { fn vr_definitions(&self) -> HashSet { - match self { - IrOperation::GetFieldRef(_) => HashSet::new(), - IrOperation::GetFieldRefMut(_) => HashSet::new(), - IrOperation::ReadField(_) => HashSet::new(), - IrOperation::Load(ir_expression) => ir_expression.vr_definitions(), - IrOperation::Add(ir_add) => ir_add.vr_definitions(), - IrOperation::Subtract(ir_subtract) => ir_subtract.vr_definitions(), - IrOperation::Multiply(ir_multiply) => ir_multiply.vr_definitions(), - IrOperation::Call(ir_call) => ir_call.vr_definitions(), - IrOperation::Allocate(_) => HashSet::new(), - } + HashSet::new() } fn vr_uses(&self) -> HashSet { @@ -79,63 +59,21 @@ impl VrUser for IrOperation { IrOperation::GetFieldRefMut(ir_get_field_ref_mut) => ir_get_field_ref_mut.vr_uses(), IrOperation::ReadField(ir_read_field) => ir_read_field.vr_uses(), IrOperation::Load(ir_expression) => ir_expression.vr_uses(), - IrOperation::Add(ir_add) => ir_add.vr_uses(), - IrOperation::Subtract(ir_subtract) => ir_subtract.vr_uses(), - IrOperation::Multiply(ir_multiply) => ir_multiply.vr_uses(), + IrOperation::Binary(ir_binary) => ir_binary.vr_uses(), IrOperation::Call(ir_call) => ir_call.vr_uses(), IrOperation::Allocate(_) => HashSet::new(), } } - fn propagate_spills(&mut self, spills: &HashSet) { - match self { - IrOperation::GetFieldRef(_) => {} - IrOperation::GetFieldRefMut(_) => {} - IrOperation::ReadField(_) => {} - IrOperation::Load(ir_expression) => { - ir_expression.propagate_spills(spills); - } - IrOperation::Add(ir_add) => { - ir_add.propagate_spills(spills); - } - IrOperation::Subtract(ir_subtract) => { - ir_subtract.propagate_spills(spills); - } - IrOperation::Multiply(ir_multiply) => { - ir_multiply.propagate_spills(spills); - } - IrOperation::Call(ir_call) => { - ir_call.propagate_spills(spills); - } - IrOperation::Allocate(_) => (), - } + fn propagate_spills(&mut self, _spills: &HashSet) { + // no-op } fn propagate_register_assignments( &mut self, - assignments: &HashMap, + _assignments: &HashMap, ) { - match self { - IrOperation::GetFieldRef(_) => {} - IrOperation::GetFieldRefMut(_) => {} - IrOperation::ReadField(_) => {} - IrOperation::Load(ir_expression) => { - ir_expression.propagate_register_assignments(assignments); - } - IrOperation::Add(ir_add) => { - ir_add.propagate_register_assignments(assignments); - } - IrOperation::Subtract(ir_subtract) => { - ir_subtract.propagate_register_assignments(assignments); - } - IrOperation::Multiply(ir_multiply) => { - ir_multiply.propagate_register_assignments(assignments); - } - IrOperation::Call(ir_call) => { - ir_call.propagate_register_assignments(assignments); - } - IrOperation::Allocate(_) => (), - } + // no-op } fn propagate_stack_offsets(&mut self, _counter: &mut OffsetCounter) { diff --git a/dmc-lib/src/ir/ir_subtract.rs b/dmc-lib/src/ir/ir_subtract.rs deleted file mode 100644 index e505c11..0000000 --- a/dmc-lib/src/ir/ir_subtract.rs +++ /dev/null @@ -1,63 +0,0 @@ -use crate::ir::ir_expression::IrExpression; -use crate::ir::ir_variable::IrVrVariableDescriptor; -use crate::ir::register_allocation::{OffsetCounter, VrUser}; -use dvm_lib::instruction::SubtractOperand; -use std::collections::{HashMap, HashSet}; -use std::fmt::{Display, Formatter}; - -pub struct IrSubtract { - left: Box, - right: Box, -} - -impl IrSubtract { - pub fn new(left: IrExpression, right: IrExpression) -> Self { - Self { - left: left.into(), - right: right.into(), - } - } - - pub fn operand_pair(&self) -> (SubtractOperand, SubtractOperand) { - (self.left.subtract_operand(), self.right.subtract_operand()) - } -} - -impl VrUser for IrSubtract { - fn vr_definitions(&self) -> HashSet { - [&self.left, &self.right] - .iter() - .flat_map(|expression| expression.vr_definitions()) - .collect() - } - - fn vr_uses(&self) -> HashSet { - [&self.left, &self.right] - .iter() - .flat_map(|expression| expression.vr_uses()) - .collect() - } - - fn propagate_spills(&mut self, spills: &HashSet) { - self.left.propagate_spills(spills); - self.right.propagate_spills(spills); - } - - fn propagate_register_assignments( - &mut self, - assignments: &HashMap, - ) { - self.left.propagate_register_assignments(assignments); - self.right.propagate_register_assignments(assignments); - } - - fn propagate_stack_offsets(&mut self, _counter: &mut OffsetCounter) { - // no-op - } -} - -impl Display for IrSubtract { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{} - {}", self.left, self.right) - } -} diff --git a/dmc-lib/src/ir/mod.rs b/dmc-lib/src/ir/mod.rs index 1302c43..ebef855 100644 --- a/dmc-lib/src/ir/mod.rs +++ b/dmc-lib/src/ir/mod.rs @@ -1,7 +1,7 @@ mod assemble; -pub mod ir_add; pub mod ir_allocate; pub mod ir_assign; +pub mod ir_binary_operation; pub mod ir_block; pub mod ir_call; pub mod ir_class; @@ -9,7 +9,6 @@ pub mod ir_expression; pub mod ir_function; pub mod ir_get_field_ref; pub mod ir_get_field_ref_mut; -pub mod ir_multiply; pub mod ir_operation; pub mod ir_parameter; pub mod ir_parameter_or_variable; @@ -17,7 +16,6 @@ pub mod ir_read_field; pub mod ir_return; pub mod ir_set_field; pub mod ir_statement; -pub mod ir_subtract; pub mod ir_variable; mod register_allocation; mod util;