diff --git a/src/generator/mod.rs b/src/generator/mod.rs index e7357f2..19784f2 100644 --- a/src/generator/mod.rs +++ b/src/generator/mod.rs @@ -1,4 +1,4 @@ -use crate::parser::node_type::Program; +use crate::parser::node_type::*; pub mod js; pub mod x86; diff --git a/src/generator/x86.rs b/src/generator/x86.rs index fc1edd9..65056f9 100644 --- a/src/generator/x86.rs +++ b/src/generator/x86.rs @@ -1,25 +1,91 @@ use crate::generator::Generator; -use crate::parser::node_type::Function; -use crate::parser::node_type::Program; +use crate::parser::node_type::{Function, Program, Statement}; + +struct Assembly { + asm: Vec, +} + +impl Into for Assembly { + fn into(self) -> String { + self.build() + } +} + +impl Assembly { + fn new() -> Assembly { + Assembly { asm: vec![] } + } + + fn add>(&mut self, string: S) { + self.asm.push(string.into()) + } + + fn add_all>(&mut self, strings: Vec) { + for string in strings { + self.asm.push(string.into()) + } + } + + fn build(&self) -> String { + self.asm.join("\n") + } +} pub struct X86Generator; impl Generator for X86Generator { fn generate(prog: Program) -> String { - return prog - .func - .into_iter() - .map(|f| generate_function(f)) - .collect(); + Self::new().gen_program(prog).build() } } -fn generate_function(func: Function) -> String { - format!( - " - .globl {F} - {F}: - ", - F = func.name - ) +impl X86Generator { + fn new() -> Self { + X86Generator {} + } + + fn gen_program(&mut self, prog: Program) -> Assembly { + 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 + } }