updated compiler with support for more operators.

(only the unary operators from this are implemented for now)
This commit is contained in:
2026-02-08 20:03:31 +00:00
parent 9f35fc9415
commit 328741eb51
5 changed files with 868 additions and 358 deletions
+33 -22
View File
@@ -510,7 +510,7 @@ impl CodeGenerator {
code.push("\tpop zero".to_string());
}
// Comparison operators - return 1 (true) or 0 (false)
BinaryOperator::Eq => {
BinaryOperator::Equal => {
code.push(format!("\tcmp {}, {}", left_reg, right_reg));
code.push(format!("\tlli 1, {}", result_reg));
let end_label = format!("_cmp_end_{}", self.get_unique_label());
@@ -518,7 +518,7 @@ impl CodeGenerator {
code.push(format!("\tlli 0, {}", result_reg));
code.push(format!("{}:", end_label));
}
BinaryOperator::Ne => {
BinaryOperator::NotEqual => {
code.push(format!("\tcmp {}, {}", left_reg, right_reg));
code.push(format!("\tlli 1, {}", result_reg));
let end_label = format!("_cmp_end_{}", self.get_unique_label());
@@ -526,7 +526,7 @@ impl CodeGenerator {
code.push(format!("\tlli 0, {}", result_reg));
code.push(format!("{}:", end_label));
}
BinaryOperator::Lt => {
BinaryOperator::LessThan => {
code.push(format!("\tcmp {}, {}", left_reg, right_reg));
code.push(format!("\tlli 1, {}", result_reg));
let end_label = format!("_cmp_end_{}", self.get_unique_label());
@@ -534,7 +534,7 @@ impl CodeGenerator {
code.push(format!("\tlli 0, {}", result_reg));
code.push(format!("{}:", end_label));
}
BinaryOperator::Le => {
BinaryOperator::LessOrEqual => {
code.push(format!("\tcmp {}, {}", left_reg, right_reg));
code.push(format!("\tlli 1, {}", result_reg));
let end_label = format!("_cmp_end_{}", self.get_unique_label());
@@ -542,7 +542,7 @@ impl CodeGenerator {
code.push(format!("\tlli 0, {}", result_reg));
code.push(format!("{}:", end_label));
}
BinaryOperator::Gt => {
BinaryOperator::GreaterThan => {
code.push(format!("\tcmp {}, {}", left_reg, right_reg));
code.push(format!("\tlli 1, {}", result_reg));
let end_label = format!("_cmp_end_{}", self.get_unique_label());
@@ -550,7 +550,7 @@ impl CodeGenerator {
code.push(format!("\tlli 0, {}", result_reg));
code.push(format!("{}:", end_label));
}
BinaryOperator::Ge => {
BinaryOperator::GreaterOrEqual => {
code.push(format!("\tcmp {}, {}", left_reg, right_reg));
code.push(format!("\tlli 1, {}", result_reg));
let end_label = format!("_cmp_end_{}", self.get_unique_label());
@@ -581,13 +581,6 @@ impl CodeGenerator {
arg_regs.push(arg_reg);
}
// Save caller-saved registers and track which ones we saved
// old method, inefficient.
// let saved_regs = self.allocator.get_caller_saved_registers();
// for reg in &saved_regs {
// code.push(format!("\tpush {}", reg));
// }
// Save caller-saved registers and track which ones we saved
let saved_regs = self.allocator.get_caller_saved_registers();
for reg in &saved_regs {
@@ -604,9 +597,6 @@ impl CodeGenerator {
));
}
// if GLOBAL_METHODS.contains_key(name.name.as_str()) {
// code.push(format!("\tcall {}",
// GLOBAL_METHODS[name.name.as_str()])); } else
if self.symbols.contains(&name.name) {
// Call local function
code.push(format!("\tcall {}", name));
@@ -644,11 +634,6 @@ impl CodeGenerator {
}
}
// Restore caller-saved registers in reverse order (LIFO)
// for reg in saved_regs.iter().rev() {
// code.push(format!("\tpop {}", reg));
// }
// Free argument registers
for reg in arg_regs {
self.allocator.free_temp(reg);
@@ -677,7 +662,9 @@ impl CodeGenerator {
UnaryOperator::Dereference => {
code.push(format!("\tldw {}, {}", operand_reg, result_reg));
}
UnaryOperator::Reference => {
UnaryOperator::AddressOf => {
// ensure the referenced variable is on the stack and return its
// address.
let (offset, alloc_code) =
self.allocator.free_register(&operand_reg)?;
code.extend(alloc_code);
@@ -687,6 +674,28 @@ impl CodeGenerator {
result_reg
));
}
UnaryOperator::SizeOf => {
if let Ok(id) = operand.type_id() {
let size = id.size();
code.push(format!("\tmov {}, {}", size, result_reg));
}
}
UnaryOperator::CastAs => {} /* this should be removed once the */
// semantic analyser can handle it!
UnaryOperator::Increment => {
// prefix increment
code.push(format!("\tmov {}, {}", operand_reg, result_reg));
code.push(format!("\taddi {}, {}, 1", operand_reg, operand_reg));
}
UnaryOperator::Decrement => {
// prefix decrement
code.push(format!("\tmov {}, {}", operand_reg, result_reg));
code.push(format!("\tsubi {}, {}, 1", operand_reg, operand_reg));
}
UnaryOperator::BitwiseNot => {
code.push(format!("\tnot {}, {}", operand_reg, result_reg));
}
UnaryOperator::LogicalNot => unimplemented!(),
}
self.allocator.free_temp(operand_reg);
@@ -694,6 +703,8 @@ impl CodeGenerator {
}
Expression::Empty => Ok((Register::Null, code)),
_ => unimplemented!(),
}
}
+2 -2
View File
@@ -132,7 +132,7 @@ impl RegisterAllocator {
}
// This is a true temporary - safe to free
if reg != Register::Zero {
if !matches!(reg, Register::Zero | Register::Null) {
self.in_use.insert(reg, false);
}
}
@@ -141,7 +141,7 @@ impl RegisterAllocator {
// Check if this variable is in a register
if let Some(location) = self.variable_locations.get(var).cloned() {
if let Some(reg) = location.register
&& reg != Register::Zero
&& !matches!(reg, Register::Zero | Register::Null)
{
self.register_contents.remove(&reg);
self.in_use.insert(reg, false);