diff --git a/.gitignore b/.gitignore index 5bf9b1f..6bfdd94 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ target/ *.s -*.o \ No newline at end of file +*.o +hello_world diff --git a/bfox-asmgen/src/lib.rs b/bfox-asmgen/src/lib.rs index 393e924..5943d75 100644 --- a/bfox-asmgen/src/lib.rs +++ b/bfox-asmgen/src/lib.rs @@ -34,7 +34,7 @@ impl AsmGen { self.asm_type = t; } - pub fn generate(&mut self, tokens: Vec, obj_path: PathBuf) -> anyhow::Result<()> { + pub fn generate(&mut self, mut tokens: Vec, obj_path: PathBuf) -> anyhow::Result<()> { let asm_path = obj_path.with_extension("s"); let fd_ = std::fs::File::options() @@ -55,6 +55,8 @@ impl AsmGen { let mut bw = BufWriter::new(fd); + tokens.reverse(); + match self.asm_type { AsmType::X86_64_NASM => targets::compile_x86_64_nasm(self, tokens, &mut bw)?, } diff --git a/bfox-asmgen/src/targets/x86_64_nasm.rs b/bfox-asmgen/src/targets/x86_64_nasm.rs index f1cafcf..2a83112 100644 --- a/bfox-asmgen/src/targets/x86_64_nasm.rs +++ b/bfox-asmgen/src/targets/x86_64_nasm.rs @@ -6,30 +6,159 @@ use bfox_parser::types::token::TokenType; use crate::AsmGen; -pub fn compile_x86_64_nasm(_asm_gen: &mut AsmGen, tokens: Vec, bw: &mut BufWriter) -> Result<()>{ +pub fn compile_x86_64_nasm(_asm_gen: &mut AsmGen, mut tokens: Vec, bw: &mut BufWriter) -> Result<()>{ writeln!(bw, "BITS 64")?; writeln!(bw, "section .bss")?; writeln!(bw, " memory: resb 30000")?; - writeln!(bw, " mem_ptr: resq 1")?; - - // writeln!(bw, "section .data")?; - // writeln!(bw, " input db 0")?; writeln!(bw, "section .text")?; + writeln!(bw, "global _start")?; writeln!(bw, "_start:")?; + writeln!(bw, " mov rbx, memory")?; - for t in tokens { + let mut li = 0; + let mut lia = Vec::new(); + + while let Some(t) = tokens.pop() { match t.typ { TokenType::Add => { - writeln!(bw, " mov rax, memory")?; - writeln!(bw, " add rax, [mem_ptr]")?; - writeln!(bw, " inc byte [rax]")?; + let mut i: isize = 1; + + while let Some(t) = tokens.last() { + if t.typ == TokenType::Add { + log::debug!("{:?}", t.typ); + i += 1; + } else if t.typ == TokenType::Sub { + log::debug!("{:?}", t.typ); + i -= 1; + } else { + break; + } + tokens.pop(); + } + + + if i == 0 { continue; } + + writeln!(bw, " ; add")?; + if i > 0 { + writeln!(bw, " add byte [rbx], {i}")?; + } else { + writeln!(bw, " sub byte [rbx], {}", i * -1)?; + } } - ut => todo!("{ut:?}") + TokenType::Sub => { + let mut i: isize = -1; + + while let Some(t) = tokens.last() { + if t.typ == TokenType::Add { + i += 1; + } else if t.typ == TokenType::Sub { + i -= 1; + } else { + break; + } + tokens.pop(); + } + + if i == 0 { continue; } + + writeln!(bw, " ; sub")?; + if i > 0 { + writeln!(bw, " add byte [rbx], {i}")?; + } else { + writeln!(bw, " sub byte [rbx], {}", i * -1)?; + } + } + TokenType::Left => { + let mut i: isize = -1; + + while let Some(t) = tokens.last() { + if t.typ == TokenType::Right { + i += 1; + } else if t.typ == TokenType::Left { + i -= 1; + } else { + break; + } + tokens.pop(); + } + + if i == 0 { continue; } + + writeln!(bw, " ; left")?; + if i > 0 { + writeln!(bw, " add qword rbx, {i}")?; + } else { + writeln!(bw, " sub qword rbx, {}", i * -1)?; + } + }, + TokenType::Right => { + let mut i: isize = 1; + + while let Some(t) = tokens.last() { + if t.typ == TokenType::Right { + i += 1; + } else if t.typ == TokenType::Left { + i -= 1; + } else { + break; + } + tokens.pop(); + } + + if i == 0 { continue; } + + writeln!(bw, " ; right")?; + if i > 0 { + writeln!(bw, " add qword rbx, {i}")?; + } else { + writeln!(bw, " sub qword rbx, {}", i * -1)?; + } + }, + TokenType::LoopL => { + lia.push(li); + + + writeln!(bw, ".o{li}:")?; + writeln!(bw, " mov rcx, memory")?; + writeln!(bw, " add rcx, rbx")?; + writeln!(bw, " cmp rcx, 0")?; + writeln!(bw, " je .c{li}")?; + li += 1; + }, + // [ [[]] [[]] ] + TokenType::LoopR => { + let Some(i) = lia.pop() else { + log::error!("Inbalanced amount of braces [ ]"); + break; + }; + writeln!(bw, ".c{i}:")?; + writeln!(bw, " mov rcx, memory")?; + writeln!(bw, " add rcx, rbx")?; + writeln!(bw, " cmp rcx, 0")?; + writeln!(bw, " je .o{i}")?; + }, + TokenType::Print => { + writeln!(bw, " mov rcx, memory")?; + writeln!(bw, " add rcx, rbx")?; + writeln!(bw, " mov rax, 1")?; + writeln!(bw, " mov rdi, 1")?; + writeln!(bw, " mov rsi, rax")?; + writeln!(bw, " mov rdx, 1")?; + }, + TokenType::Input => { + writeln!(bw, " mov rcx, memory")?; + writeln!(bw, " add rcx, rbx")?; + writeln!(bw, " mov rax, 0")?; + writeln!(bw, " mov rdi, 1")?; + writeln!(bw, " mov rsi, rax")?; + writeln!(bw, " mov rdx, 1")?; + }, } } diff --git a/bfox-parser/src/types/token.rs b/bfox-parser/src/types/token.rs index 6b07c96..2f2996f 100644 --- a/bfox-parser/src/types/token.rs +++ b/bfox-parser/src/types/token.rs @@ -7,7 +7,7 @@ pub struct Token { pub loc: Loc, } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum TokenType { Add, Sub, diff --git a/bfox/src/main.rs b/bfox/src/main.rs index d4dc6b3..46055d4 100644 --- a/bfox/src/main.rs +++ b/bfox/src/main.rs @@ -19,7 +19,7 @@ fn main() -> anyhow::Result<()> { let tokens = parser.tokens(); - log::debug!("{tokens:?}"); + // log::debug!("{tokens:?}"); let mut asmgen = bfox_asmgen::AsmGen::new(); diff --git a/hello_word.bf b/hello_world.bf similarity index 100% rename from hello_word.bf rename to hello_world.bf