Skip to content

Commit

Permalink
refactor: less .unwrap()s
Browse files Browse the repository at this point in the history
  • Loading branch information
MilkeeyCat committed Aug 3, 2024
1 parent d2b1f13 commit bdde837
Show file tree
Hide file tree
Showing 14 changed files with 230 additions and 85 deletions.
83 changes: 61 additions & 22 deletions src/archs/amd64.rs → src/archs/amd64/amd64.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use crate::{
archs::Architecture,
archs::{ArchError, Architecture},
codegen::locations::{self, Global, Local, MoveDestination, MoveSource, Offset, SourceParam},
parser::{CmpOp, ExprLit, Expression},
register::{
allocator::{AllocatorError, RegisterAllocator},
Register,
},
scope::Scope,
types::Type,
types::{Type, TypeError},
};
use indoc::formatdoc;

Expand Down Expand Up @@ -66,7 +66,12 @@ impl Architecture for Amd64 {
}
}

fn mov(&mut self, src: MoveSource, dest: MoveDestination, scope: &Scope) {
fn mov(
&mut self,
src: MoveSource,
dest: MoveDestination,
scope: &Scope,
) -> Result<(), ArchError> {
match src {
MoveSource::Global(global, signed) => self.mov_global(global, dest, signed, scope),
MoveSource::Local(local, signed) => self.mov_local(local, dest, signed, scope),
Expand Down Expand Up @@ -199,19 +204,21 @@ impl Architecture for Amd64 {
));
}

fn ret(&mut self, r: Register, type_: Type, scope: &Scope) {
fn ret(&mut self, r: Register, type_: Type, scope: &Scope) -> Result<(), TypeError> {
self.mov_impl(
(
&MoveDestination::Register(locations::Register {
register: &r,
size: type_.size(self, scope),
size: type_.size(self, scope)?,
offset: None,
}),
type_.size(self, scope),
type_.size(self, scope)?,
),
("rax", 8),
type_.signed(),
);

Ok(())
}

fn jmp(&mut self, label: &str) {
Expand Down Expand Up @@ -293,20 +300,33 @@ impl Amd64 {
}
}

fn mov_literal(&mut self, literal: ExprLit, dest: MoveDestination, scope: &Scope) {
fn mov_literal(
&mut self,
literal: ExprLit,
dest: MoveDestination,
scope: &Scope,
) -> Result<(), ArchError> {
self.mov_impl(
(&literal, literal.type_(scope).unwrap().size(self, scope)),
(&literal, literal.type_(scope)?.size(self, scope)?),
(&dest, dest.size()),
literal.type_(scope).unwrap().signed(),
)
literal.type_(scope)?.signed(),
);

Ok(())
}

fn mov_local(&mut self, src: Local, dest: MoveDestination, signed: bool, scope: &Scope) {
fn mov_local(
&mut self,
src: Local,
dest: MoveDestination,
signed: bool,
scope: &Scope,
) -> Result<(), ArchError> {
match dest {
// NOTE: x86-64 doesn't support indirect to indirect addressing mode so we use tools we already have
MoveDestination::Local(local) => {
let mut size = src.size;
let r = self.alloc().unwrap();
let r = self.alloc()?;

self.lea(&r, src.offset);

Expand All @@ -319,7 +339,7 @@ impl Amd64 {
0 => unreachable!(),
};

let r_tmp = self.alloc().unwrap();
let r_tmp = self.alloc()?;

self.mov_register(
locations::Register {
Expand All @@ -334,7 +354,7 @@ impl Amd64 {
}),
signed,
scope,
);
)?;
self.mov_register(
locations::Register {
size: chunk_size,
Expand All @@ -347,23 +367,32 @@ impl Amd64 {
}),
signed,
scope,
);
)?;

self.free(r_tmp);
size -= chunk_size;
}

self.free(r).unwrap();
self.free(r)?;
}
MoveDestination::Global(_) => {
todo!();
}
MoveDestination::Register(register) => {
self.mov_impl((&src, src.size), (&register, register.size), signed);
}
}
};

Ok(())
}

fn mov_param(&mut self, src: SourceParam, dest: MoveDestination, signed: bool, scope: &Scope) {
fn mov_param(
&mut self,
src: SourceParam,
dest: MoveDestination,
signed: bool,
scope: &Scope,
) -> Result<(), ArchError> {
self.mov(
MoveSource::Register(
locations::Register {
Expand All @@ -378,10 +407,18 @@ impl Amd64 {
),
dest,
scope,
);
)?;

Ok(())
}

fn mov_global(&self, _src: Global, _dest: MoveDestination, _signed: bool, _scope: &Scope) {
fn mov_global(
&self,
_src: Global,
_dest: MoveDestination,
_signed: bool,
_scope: &Scope,
) -> Result<(), ArchError> {
todo!();
}

Expand All @@ -391,8 +428,10 @@ impl Amd64 {
dest: MoveDestination,
signed: bool,
_: &Scope,
) {
self.mov_impl((&src, src.size), (&dest, dest.size()), signed)
) -> Result<(), ArchError> {
self.mov_impl((&src, src.size), (&dest, dest.size()), signed);

Ok(())
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/archs/amd64/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod amd64;

pub use amd64::Amd64;
12 changes: 9 additions & 3 deletions src/archs/arch.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use super::ArchError;
use crate::{
codegen::locations::{self, MoveDestination, MoveSource},
parser::CmpOp,
register::{allocator::AllocatorError, Register},
scope::Scope,
types::Type,
types::{Type, TypeError},
};

pub trait Architecture {
Expand All @@ -18,7 +19,12 @@ pub trait Architecture {
where
Self: Sized;
fn declare(&mut self, name: &str, size: usize);
fn mov(&mut self, src: MoveSource, dest: MoveDestination, scope: &Scope);
fn mov(
&mut self,
src: MoveSource,
dest: MoveDestination,
scope: &Scope,
) -> Result<(), ArchError>;
fn negate(&mut self, r: &Register);
fn not(&mut self, dest: &Register, src: &Register);
fn add(&mut self, dest: &MoveDestination, src: &locations::Register);
Expand All @@ -28,7 +34,7 @@ pub trait Architecture {
fn cmp(&mut self, dest: &Register, src: &Register, cmp: CmpOp);
fn fn_preamble(&mut self, name: &str, stackframe: usize);
fn fn_postamble(&mut self, name: &str, stackframe: usize);
fn ret(&mut self, r: Register, type_: Type, scope: &Scope);
fn ret(&mut self, r: Register, type_: Type, scope: &Scope) -> Result<(), TypeError>;
fn jmp(&mut self, label: &str);
fn call_fn(&mut self, name: &str, r: Option<&Register>);
fn move_function_argument(&mut self, r: Register, i: usize);
Expand Down
31 changes: 31 additions & 0 deletions src/archs/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use crate::{
parser::ExprError, register::allocator::AllocatorError, symbol_table::SymbolTableError,
types::TypeError,
};

pub enum ArchError {
Type(TypeError),
Allocator(AllocatorError),
SymbolTable(SymbolTableError),
}

impl From<TypeError> for ArchError {
fn from(value: TypeError) -> Self {
Self::Type(value)
}
}

impl From<AllocatorError> for ArchError {
fn from(value: AllocatorError) -> Self {
Self::Allocator(value)
}
}

impl From<ExprError> for ArchError {
fn from(value: ExprError) -> Self {
match value {
ExprError::Type(e) => Self::Type(e),
ExprError::SymbolTable(e) => Self::SymbolTable(e),
}
}
}
7 changes: 5 additions & 2 deletions src/archs/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
mod amd64;
mod arch;
mod error;

pub use amd64::Amd64;
pub use arch::Architecture;
pub use error::ArchError;

mod amd64;
pub use amd64::*;
Loading

0 comments on commit bdde837

Please sign in to comment.