-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[TARGET] creating registry for having the ability to use multiple dif…
…ferent targets
- Loading branch information
Showing
14 changed files
with
400 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
use std::error::Error; | ||
|
||
use super::Token; | ||
|
||
/// An wrapper trait for assembly compilers | ||
pub trait Compiler { | ||
/// Creates an new assembly compiler | ||
fn new(&self, tokens: Vec<Token>) -> Box<dyn Compiler>; | ||
/// compiles an assembly string into machine code | ||
fn parse(&mut self) -> Result<(), Box<dyn Error>>; | ||
/// Returns the output machine code | ||
fn out(&self) -> Vec<u8>; | ||
|
||
#[doc(hidden)] | ||
fn boxed(&self) -> Box<dyn Compiler>; | ||
} | ||
|
||
impl Clone for Box<dyn Compiler> { | ||
fn clone(&self) -> Self { | ||
self.boxed() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
use std::error::Error; | ||
|
||
use super::Token; | ||
|
||
/// The lexer trait | ||
pub trait Lexer { | ||
/// lexes the string | ||
fn lex(&self, string: String) -> Result<Vec<Token>, Box<dyn Error>>; | ||
|
||
/// Returns self into a boxed lexer trait | ||
fn boxed(&self) -> Box<dyn Lexer>; | ||
} | ||
|
||
impl Clone for Box<dyn Lexer> { | ||
fn clone(&self) -> Self { | ||
self.boxed() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
use std::{collections::HashMap, error::Error, fmt::Display}; | ||
|
||
use crate::prelude::{Block, Function}; | ||
|
||
use super::{Arch, CallConv, TargetBackendDescr, Triple}; | ||
|
||
/// The target registry: manages different targets | ||
pub struct TargetRegistry<'a> { | ||
targets: HashMap<Arch, TargetBackendDescr<'a>> | ||
} | ||
|
||
impl<'a> TargetRegistry<'a> { | ||
/// Creates an new backend registry | ||
pub fn new() -> Self { | ||
Self { | ||
targets: HashMap::new() | ||
} | ||
} | ||
|
||
/// Adds an new target architecture | ||
pub fn add(&mut self, arch: Arch, descr: TargetBackendDescr<'a>) { | ||
self.targets.insert(arch, descr); | ||
} | ||
|
||
/// Sets the calling convention to use for the specified architecture | ||
/// If it isn't found the function does noting | ||
pub fn setCallingConventionForTarget(&mut self, arch: Arch, call: CallConv) { | ||
if let Some(target) = self.targets.get_mut(&arch) { | ||
target.call = call; | ||
} | ||
} | ||
|
||
/// returns the `TargetBackendDescr` for the triple (also it adjusts it's calling convention ...) | ||
pub fn getBasedOnTriple(&mut self, triple: Triple) -> Result<&mut TargetBackendDescr<'a>, Box<dyn Error>> { | ||
if let Some(descr) = self.targets.get_mut(&triple.arch) { | ||
*descr = descr.init.unwrap()(triple.getCallConv()?); | ||
|
||
Ok(descr) | ||
} else { | ||
Err(Box::from( | ||
RegistryError::UnsuportedArch(triple.arch) | ||
)) | ||
} | ||
} | ||
|
||
/// Builds the ir of the given triple into text assembly code | ||
pub fn buildAsmForTarget(&mut self, triple: Triple, block: &Block, funct: &Function) -> Result<Vec<String>, Box<dyn Error>> { | ||
if let Some(org) = self.targets.get_mut(&triple.arch) { | ||
Ok( | ||
org.buildAsm.unwrap()( | ||
&block, &funct, | ||
&org.init.unwrap()(triple.getCallConv()?).call, // Unnessecary (and slow) but prevents | ||
&mut org.init.unwrap()(triple.getCallConv()?)) // lifetime issues | ||
) | ||
} else { | ||
Err(Box::from( | ||
RegistryError::UnsuportedArch(triple.arch) | ||
)) | ||
} | ||
} | ||
} | ||
|
||
/// Stores errors which can occure in the `getBasedOnTriple` function in the `TargetRegistry` | ||
#[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
pub enum RegistryError { | ||
/// An unsupported architecture | ||
UnsuportedArch(Arch), | ||
} | ||
|
||
impl Display for RegistryError { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
write!(f, "{}", match self { | ||
RegistryError::UnsuportedArch(arch) => format!("unsuported architecture: {:?}", arch), | ||
}) | ||
} | ||
} | ||
|
||
impl Error for RegistryError {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.