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, bw: &mut BufWriter) -> 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(()) }