Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
tests
test.l2
output
test.l3
31 changes: 22 additions & 9 deletions src/backend/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ _main:

pub struct CodeGenerator {
ir_graphs: Vec<IRGraph>,
jump_label: HashMap<usize, String>,
jump_label: HashMap<(String, BlockIndex), String>,
}

impl CodeGenerator {
Expand Down Expand Up @@ -140,7 +140,10 @@ impl CodeGenerator {
registers: &Registers,
) -> String {
let mut code = String::new();
let block_label = self.jump_label.get(&block_index).unwrap();
let block_label = self
.jump_label
.get(&(ir_graph.name().to_string(), block_index))
.unwrap();
code.push_str(&format!("{}:\n", block_label));

for (node_index, node) in block.get_nodes().iter().enumerate() {
Expand Down Expand Up @@ -324,7 +327,10 @@ impl CodeGenerator {
node,
);
let following_block_index = jump_information.get(&node_index).unwrap();
let label = self.jump_label.get(following_block_index).unwrap();
let label = self
.jump_label
.get(&(ir_graph.name().to_string(), *following_block_index))
.unwrap();
code.push_str(&self.generate_phi_moves(
block_index,
*following_block_index,
Expand Down Expand Up @@ -372,7 +378,7 @@ impl CodeGenerator {
let following_block_index = jump_information.get(&node_index).unwrap();
let jump_label = self
.jump_label
.get(following_block_index)
.get(&(ir_graph.name().to_string(), *following_block_index))
.expect("Expected jump label for false if");
code.push_str(&self.generate_phi_moves(
block_index,
Expand Down Expand Up @@ -620,7 +626,10 @@ impl CodeGenerator {
registers: &Registers,
) -> Option<String> {
let mut code = String::new();
let jump_label = self.jump_label.get(&jump_target).unwrap();
let jump_label = self
.jump_label
.get(&(ir_graph.name().to_string(), jump_target))
.unwrap();
match comparision {
Node::Lower(data)
| Node::LowerEquals(data)
Expand Down Expand Up @@ -898,20 +907,24 @@ fn move_stack_variable(register: &Box<dyn Register>) -> String {
code
}

fn calculate_jump_label(ir_graphs: &Vec<IRGraph>) -> HashMap<usize, String> {
fn calculate_jump_label(ir_graphs: &Vec<IRGraph>) -> HashMap<(String, BlockIndex), String> {
let mut jump_label = HashMap::new();
for ir_graph in ir_graphs {
for (block_index, block) in ir_graph.get_blocks().iter().enumerate() {
calculate_jump_label_block(block_index, block, &mut jump_label);
calculate_jump_label_block(block_index, ir_graph, block, &mut jump_label);
}
}
jump_label
}

fn calculate_jump_label_block<'a>(
block_index: BlockIndex,
ir_graph: &IRGraph,
_block: &Block,
current: &mut HashMap<usize, String>,
current: &mut HashMap<(String, BlockIndex), String>,
) {
current.insert(block_index, format!("LC{}", block_index));
current.insert(
(ir_graph.name().to_string(), block_index),
format!("LC{}{}", ir_graph.name(), block_index),
);
}
149 changes: 149 additions & 0 deletions src/ir/ast/assignment_tree.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
use crate::{
ir::{ast::ToIR, block::NodeIndex},
lexer::operator::AssignmentOperator,
parser::ast::assignment_tree::AssignmentTree,
};

use super::IRConstructor;

impl ToIR for AssignmentTree {
fn to_ir(&self, constructor: &mut IRConstructor) -> Option<NodeIndex> {
let rhs = self
.expression()
.to_ir(constructor)
.expect("Invalid expression!");
match self.operator() {
AssignmentOperator::AssignMinus => {
let lhs = constructor.read_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
);
let desugar = constructor.create_sub(lhs, rhs);
constructor.write_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
desugar,
);
}
AssignmentOperator::AssignPlus => {
let lhs = constructor.read_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
);
let desugar = constructor.create_add(lhs, rhs);
constructor.write_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
desugar,
);
}
AssignmentOperator::AssignMul => {
let lhs = constructor.read_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
);
let desugar = constructor.create_mul(lhs, rhs);
constructor.write_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
desugar,
);
}
AssignmentOperator::AssignDiv => {
let lhs = constructor.read_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
);
let div = constructor.create_div(lhs, rhs);
let desugar = constructor.create_div_mod_projection(div);
constructor.write_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
desugar,
);
}
AssignmentOperator::AssignMod => {
let lhs = constructor.read_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
);
let mod_node = constructor.create_mod(lhs, rhs);
let desugar = constructor.create_div_mod_projection(mod_node);
constructor.write_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
desugar,
);
}
AssignmentOperator::AssignShiftLeft => {
let lhs = constructor.read_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
);
let desugar = constructor.create_shift_left(lhs, rhs);
constructor.write_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
desugar,
);
}
AssignmentOperator::AssignShiftRight => {
let lhs = constructor.read_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
);
let desugar = constructor.create_shift_right(lhs, rhs);
constructor.write_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
desugar,
);
}
AssignmentOperator::AssignBitwiseOr => {
let lhs = constructor.read_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
);
let desugar = constructor.create_or(lhs, rhs);
constructor.write_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
desugar,
);
}
AssignmentOperator::AssignBitwiseAnd => {
let lhs = constructor.read_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
);
let desugar = constructor.create_and(lhs, rhs);
constructor.write_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
desugar,
);
}
AssignmentOperator::AssignBitwiseXor => {
let lhs = constructor.read_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
);
let desugar = constructor.create_xor(lhs, rhs);
constructor.write_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
desugar,
);
}
AssignmentOperator::Assign => {
constructor.write_variable(
self.lvalue().identifier().name().clone(),
constructor.current_block(),
rhs,
);
}
AssignmentOperator::AssignBitwiseNot => todo!(),
};
return None;
}
}
47 changes: 47 additions & 0 deletions src/ir/ast/binary_operation_tree.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use crate::{
ir::{ast::ToIR, block::NodeIndex},
lexer::operator::BinaryOperator,
parser::ast::binary_operation_tree::BinaryOperationTree,
};

use super::IRConstructor;

impl ToIR for BinaryOperationTree {
fn to_ir(&self, constructor: &mut IRConstructor) -> Option<NodeIndex> {
let lhs_node = self
.lhs()
.to_ir(constructor)
.expect("Expected LHS to be expression");
let rhs_node = self
.rhs()
.to_ir(constructor)
.expect("Expected RHS to be expression");
let result = match self.operator() {
BinaryOperator::Minus => constructor.create_sub(lhs_node, rhs_node),
BinaryOperator::Plus => constructor.create_add(lhs_node, rhs_node),
BinaryOperator::Mul => constructor.create_mul(lhs_node, rhs_node),
BinaryOperator::Div => {
let div_node = constructor.create_div(lhs_node, rhs_node);
constructor.create_div_mod_projection(div_node)
}
BinaryOperator::Mod => {
let mod_node = constructor.create_mod(lhs_node, rhs_node);
constructor.create_div_mod_projection(mod_node)
}
BinaryOperator::ShiftLeft => constructor.create_shift_left(lhs_node, rhs_node),
BinaryOperator::ShiftRight => constructor.create_shift_right(lhs_node, rhs_node),
BinaryOperator::Lower => constructor.create_lower(lhs_node, rhs_node),
BinaryOperator::LowerEquals => constructor.create_lower_equals(lhs_node, rhs_node),
BinaryOperator::Equals => constructor.create_equals(lhs_node, rhs_node),
BinaryOperator::NotEquals => constructor.create_not_equals(lhs_node, rhs_node),
BinaryOperator::HigherEquals => constructor.create_higher_equals(lhs_node, rhs_node),
BinaryOperator::Higher => constructor.create_higher(lhs_node, rhs_node),
BinaryOperator::BitwiseOr => constructor.create_or(lhs_node, rhs_node),
BinaryOperator::BitwiseAnd => constructor.create_and(lhs_node, rhs_node),
BinaryOperator::BitwiseXor => constructor.create_xor(lhs_node, rhs_node),
BinaryOperator::LogicalAnd => constructor.create_and(lhs_node, rhs_node),
BinaryOperator::LogicalOr => constructor.create_or(lhs_node, rhs_node),
};
Some(result)
}
}
24 changes: 24 additions & 0 deletions src/ir/ast/block_tree.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use crate::{
ir::{ast::ToIR, block::NodeIndex},
parser::ast::{
block_tree::BlockTree,
statement_tree::{ControlStatementTree, StatementTree},
},
};

use super::IRConstructor;

impl ToIR for BlockTree {
fn to_ir(&self, constructor: &mut IRConstructor) -> Option<NodeIndex> {
for statement in self.statements() {
if let StatementTree::ControlStatement(control_statement) = statement {
if let ControlStatementTree::ReturnTree(return_tree) = control_statement {
return_tree.to_ir(constructor);
break;
}
}
statement.to_ir(constructor);
}
None
}
}
30 changes: 30 additions & 0 deletions src/ir/ast/break_tree.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use tracing::debug;

use crate::{
ir::{ast::ToIR, block::NodeIndex},
parser::ast::break_tree::BreakTree,
};

use super::IRConstructor;

impl ToIR for BreakTree {
fn to_ir(&self, constructor: &mut IRConstructor) -> Option<NodeIndex> {
debug!(
"Generating IR for break statement with active loops: {:?}",
constructor.active_loop_exits
);
let jump = constructor.create_jump();
constructor.register_entry_point(
*constructor.active_loop_exits.last().unwrap(),
constructor.current_block(),
jump,
);
debug!(
"Modifying entry_points of {:?}",
constructor
.graph
.get_block_mut(*constructor.active_loop_exits.last().unwrap())
);
None
}
}
14 changes: 14 additions & 0 deletions src/ir/ast/call_tree.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use crate::{
ir::{ast::ToIR, block::NodeIndex},
parser::ast::call_tree::CallTree,
};

use super::IRConstructor;

impl ToIR for CallTree {
fn to_ir(&self, constructor: &mut IRConstructor) -> Option<NodeIndex> {
//TODO: Unimplemented
let temp = constructor.create_constant_int(0);
Some(temp)
}
}
24 changes: 24 additions & 0 deletions src/ir/ast/continue_tree.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use tracing::debug;

use crate::{
ir::{ast::ToIR, block::NodeIndex},
parser::ast::continue_tree::ContinueTree,
};

use super::IRConstructor;

impl ToIR for ContinueTree {
fn to_ir(&self, constructor: &mut IRConstructor) -> Option<NodeIndex> {
debug!(
"Generating IR for continue statement with active loops: {:?}",
constructor.active_loop_entries
);
let jump = constructor.create_jump();
constructor.register_entry_point(
*constructor.active_loop_entries.last().unwrap(),
constructor.current_block(),
jump,
);
None
}
}
Loading