Skip to content

Commit

Permalink
force push me later
Browse files Browse the repository at this point in the history
  • Loading branch information
MilkeeyCat committed May 29, 2024
1 parent 1a7711e commit ae7c44e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 68 deletions.
105 changes: 38 additions & 67 deletions src/codegen/codegen.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::{Register, RegisterAllocator};
use crate::{
parser::{
BinOp, Expr, ExprBinary, ExprLit, ExprUnary, IntLitRepr, Stmt, StmtVarDecl, Type, UnOp,
Expand All @@ -7,23 +8,9 @@ use crate::{
use indoc::{formatdoc, writedoc};
use std::{fmt::Write, fs::File};

struct Register<'a> {
name: &'a str,
in_use: bool,
}

impl<'a> Register<'a> {
pub fn new(name: &'a str) -> Self {
Self {
name,
in_use: false,
}
}
}

pub struct CodeGen<'a> {
symtable: SymbolTable,
registers: [Register<'a>; 6],
registers: RegisterAllocator<'a>,
data_section: String,
text_section: String,
bss_section: String,
Expand All @@ -33,14 +20,14 @@ impl<'a> CodeGen<'a> {
pub fn new(symtable: SymbolTable) -> Self {
Self {
symtable,
registers: [
Register::new("r8"),
Register::new("r9"),
Register::new("rdi"),
Register::new("rsi"),
Register::new("rdx"),
Register::new("rcx"),
],
registers: RegisterAllocator::new(vec![
Register::new("r8b", "r8"),
Register::new("r9b", "r9"),
Register::new("dil", "rdi"),
Register::new("sil", "rsi"),
Register::new("dl", "rdx"),
Register::new("cl", "rcx"),
]),
bss_section: "section .bss\n".to_string(),
data_section: "section .data\n".to_string(),
text_section: formatdoc!(
Expand All @@ -54,22 +41,6 @@ impl<'a> CodeGen<'a> {
}
}

fn alloc(&mut self) -> usize {
for (i, r) in self.registers.iter_mut().enumerate() {
if !r.in_use {
r.in_use = true;

return i;
}
}

panic!("All registers were in use");
}

fn free(&mut self, r: usize) {
self.registers[r].in_use = false;
}

fn declare(&mut self, var: &StmtVarDecl) {
let size = self.size(&var.type_);

Expand All @@ -83,7 +54,7 @@ impl<'a> CodeGen<'a> {
.unwrap();
}

fn expr(&mut self, expr: &Expr) -> usize {
fn expr(&mut self, expr: &Expr) -> &Register {
match expr {
Expr::Binary(bin_expr) => self.bin_expr(bin_expr),
Expr::Lit(lit) => match lit {
Expand All @@ -94,7 +65,7 @@ impl<'a> CodeGen<'a> {
}
}

fn bin_expr(&mut self, expr: &ExprBinary) -> usize {
fn bin_expr(&mut self, expr: &ExprBinary) -> &Register {
match &expr.op {
BinOp::Assign => {
let left = expr.left.as_ref();
Expand All @@ -106,7 +77,7 @@ impl<'a> CodeGen<'a> {

self.mov(name, right);

69
todo!();
} else {
panic!("Cant assign to non ident");
}
Expand Down Expand Up @@ -154,35 +125,35 @@ impl<'a> CodeGen<'a> {
}
}

fn mov(&mut self, label: &str, r: usize) {
fn mov(&mut self, label: &str, r: &Register) {
writedoc!(
self.text_section,
"
\tmov [{}], {}
",
&label,
&self.registers[r].name
r.dword(),
)
.unwrap();
}

fn load(&mut self, int_lit: &IntLitRepr) -> usize {
let r = self.alloc();
fn load(&mut self, int_lit: &IntLitRepr) -> &Register {
let r = self.registers.alloc().unwrap();

writedoc!(
self.text_section,
"
\tmov {}, {}
",
&self.registers[r].name,
r.dword(),
int_lit.to_string(),
)
.unwrap();

r
}

fn unary_expr(&mut self, unary_expr: &ExprUnary) -> usize {
fn unary_expr(&mut self, unary_expr: &ExprUnary) -> &Register {
match unary_expr.op {
UnOp::Negative => {
let r = self.expr(unary_expr.expr.as_ref());
Expand All @@ -194,67 +165,67 @@ impl<'a> CodeGen<'a> {
}
}

fn negate(&mut self, r: usize) {
fn negate(&mut self, r: &Register) {
writedoc!(
self.text_section,
"
\tneg {}
",
&self.registers[r].name,
r.dword(),
)
.unwrap();
}

fn add(&mut self, r1: usize, r2: usize) -> usize {
fn add(&mut self, r1: &Register, r2: &Register) -> &Register {
writedoc!(
self.text_section,
"
\tadd {}, {}
",
&self.registers[r1].name,
&self.registers[r2].name,
r1.dword(),
r2.dword(),
)
.unwrap();

self.free(r2);
self.registers.free(r2);

r1
}

fn sub(&mut self, r1: usize, r2: usize) -> usize {
fn sub(&mut self, r1: &Register, r2: &Register) -> &Register {
writedoc!(
self.text_section,
"
\tsub {}, {}
",
&self.registers[r1].name,
&self.registers[r2].name,
r1.dword(),
r2.dword(),
)
.unwrap();

self.free(r2);
self.registers.free(r2);

r1
}

fn mul(&mut self, r1: usize, r2: usize) -> usize {
fn mul(&mut self, r1: &Register, r2: &Register) -> &Register {
writedoc!(
self.text_section,
"
\timul {}, {}
",
&self.registers[r1].name,
&self.registers[r2].name,
r1.dword(),
r2.dword(),
)
.unwrap();

self.free(r2);
self.registers.free(r2);

r1
}

//NOTE: if mafs doesn't works, prolly because of this
fn div(&mut self, r1: usize, r2: usize) -> usize {
fn div(&mut self, r1: &Register, r2: &Register) -> &Register {
writedoc!(
self.text_section,
"
Expand All @@ -263,13 +234,13 @@ impl<'a> CodeGen<'a> {
\tidiv {}
\tmov {}, rax
",
&self.registers[r1].name,
&self.registers[r2].name,
&self.registers[r1].name,
r1.dword(),
r2.dword(),
r1.dword(),
)
.unwrap();

self.free(r2);
self.registers.free(r2);

r1
}
Expand Down
2 changes: 1 addition & 1 deletion src/codegen/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl<'a> RegisterAllocator<'a> {
Err(AllocatorError::RanOutOfRegisters)
}

pub fn free(&mut self, r: &Register<'a>) -> Result<(), AllocatorError> {
pub fn free(&mut self, r: &Register) -> Result<(), AllocatorError> {
for (i, register) in self.registers.iter().enumerate() {
if r == register {
if let RegisterStatus::Free = self.status[i] {
Expand Down

0 comments on commit ae7c44e

Please sign in to comment.