mirror of https://git.sr.ht/~garritfra/sabre
Garrit Franke
3 years ago
2 changed files with 82 additions and 16 deletions
@ -1,25 +1,91 @@ |
|||||||
use crate::generator::Generator; |
use crate::generator::Generator; |
||||||
use crate::parser::node_type::Function; |
use crate::parser::node_type::{Function, Program, Statement}; |
||||||
use crate::parser::node_type::Program; |
|
||||||
|
struct Assembly { |
||||||
|
asm: Vec<String>, |
||||||
|
} |
||||||
|
|
||||||
|
impl Into<String> for Assembly { |
||||||
|
fn into(self) -> String { |
||||||
|
self.build() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl Assembly { |
||||||
|
fn new() -> Assembly { |
||||||
|
Assembly { asm: vec![] } |
||||||
|
} |
||||||
|
|
||||||
|
fn add<S: Into<String>>(&mut self, string: S) { |
||||||
|
self.asm.push(string.into()) |
||||||
|
} |
||||||
|
|
||||||
|
fn add_all<S: Into<String>>(&mut self, strings: Vec<S>) { |
||||||
|
for string in strings { |
||||||
|
self.asm.push(string.into()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fn build(&self) -> String { |
||||||
|
self.asm.join("\n") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
pub struct X86Generator; |
pub struct X86Generator; |
||||||
|
|
||||||
impl Generator for X86Generator { |
impl Generator for X86Generator { |
||||||
fn generate(prog: Program) -> String { |
fn generate(prog: Program) -> String { |
||||||
return prog |
Self::new().gen_program(prog).build() |
||||||
.func |
|
||||||
.into_iter() |
|
||||||
.map(|f| generate_function(f)) |
|
||||||
.collect(); |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
fn generate_function(func: Function) -> String { |
impl X86Generator { |
||||||
format!( |
fn new() -> Self { |
||||||
" |
X86Generator {} |
||||||
.globl {F} |
} |
||||||
{F}: |
|
||||||
", |
fn gen_program(&mut self, prog: Program) -> Assembly { |
||||||
F = func.name |
let mut asm = Assembly::new(); |
||||||
) |
match prog { |
||||||
|
Program { func, globals } => { |
||||||
|
asm.add(".intel_syntax noprefix"); |
||||||
|
asm.add(".text"); |
||||||
|
|
||||||
|
for f in func { |
||||||
|
asm.add(self.gen_function(f)); |
||||||
|
} |
||||||
|
asm.add(".data"); |
||||||
|
for g in globals { |
||||||
|
asm.add(format!("_{0}: .word 0", g)); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
asm |
||||||
|
} |
||||||
|
|
||||||
|
fn gen_function(&mut self, func: Function) -> Assembly { |
||||||
|
let mut asm = Assembly::new(); |
||||||
|
|
||||||
|
let has_return: bool = func.statements.iter().any(|s| { |
||||||
|
if let Statement::Return(_) = *s { |
||||||
|
true |
||||||
|
} else { |
||||||
|
false |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
asm.add(format!(".globl _{}", func.name)); |
||||||
|
asm.add(format!("_{}:", func.name)); |
||||||
|
asm.add("push rbp"); |
||||||
|
asm.add("mov rbp, rsp"); |
||||||
|
|
||||||
|
if !has_return { |
||||||
|
asm.add("mov rsp, rbp"); |
||||||
|
asm.add("pop rbp"); |
||||||
|
asm.add("ret\n"); |
||||||
|
} |
||||||
|
|
||||||
|
asm |
||||||
|
} |
||||||
} |
} |
||||||
|
Loading…
Reference in new issue