172 lines
5.3 KiB
Rust
172 lines
5.3 KiB
Rust
use std::{any::Any, fs::File, io::{BufWriter, Write}};
|
|
use anyhow::Result;
|
|
use bfox_parser::types::token::Token;
|
|
use bfox_parser::types::token::TokenType;
|
|
|
|
use crate::AsmGen;
|
|
|
|
|
|
pub fn compile_x86_64_nasm(_asm_gen: &mut AsmGen, mut tokens: Vec<Token>, bw: &mut BufWriter<File>) -> Result<()>{
|
|
|
|
writeln!(bw, "BITS 64")?;
|
|
|
|
writeln!(bw, "section .bss")?;
|
|
writeln!(bw, " memory: resb 30000")?;
|
|
|
|
writeln!(bw, "section .text")?;
|
|
writeln!(bw, "global _start")?;
|
|
writeln!(bw, "_start:")?;
|
|
writeln!(bw, " mov rbx, memory")?;
|
|
|
|
let mut li = 0;
|
|
let mut lia = Vec::new();
|
|
|
|
while let Some(t) = tokens.pop() {
|
|
match t.typ {
|
|
|
|
TokenType::Add => {
|
|
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)?;
|
|
}
|
|
}
|
|
|
|
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")?;
|
|
},
|
|
|
|
}
|
|
}
|
|
|
|
// Exit
|
|
writeln!(bw, " mov rax, 60")?;
|
|
writeln!(bw, " mov rdi, 0")?;
|
|
writeln!(bw, " syscall")?;
|
|
|
|
Ok(())
|
|
} |