use std::collections::VecDeque; use crate::tokenizer::{Token, TokenType}; pub fn generate(tokens: Vec) -> String { let mut output = String::new(); // reserving mem output.push_str( "section .bss\n\ data: resb 65536\n", ); // global start label output.push_str( "global _start\n\ section .text\n\ _start:\n", ); // create the pointer for our data output.push_str("mov rdx, data\n"); let mut loops = 0; let mut stack: VecDeque = VecDeque::new(); for token in tokens { match token.r#type { TokenType::Plus(x) => { output.push_str(&format!("add byte[rdx], {x}\n")); } TokenType::Minus(x) => { output.push_str(&format!("sub byte[rdx], {x}\n")); } TokenType::MoveRight(x) => { output.push_str(&format!("add rdx, {x}\n")); } TokenType::MoveLeft(x) => { output.push_str(&format!("sub rdx, {x}\n")); } TokenType::Output => { output.push_str( "push rdx\n\ mov rax, 1\n\ mov rdi, 1\n\ mov rsi, rdx\n\ mov rdx, 1\n\ syscall\n\ pop rdx\n", ); } TokenType::Input => { output.push_str( "push rdx\n\ mov rax, 0\n\ mov rdi, 0\n\ mov rsi, rdx\n\ mov rdx, 1\n\ syscall\n\ pop rdx\n", ); } TokenType::BracketOpen => { output.push_str(&format!( ".loop_{loops}_start:\n\ cmp byte[rdx], 0\n\ je .loop_{loops}_end\n" )); stack.push_back(loops); loops += 1; } TokenType::BracketClose => { let current_loop = stack.pop_back().unwrap(); output.push_str(&format!( "cmp byte[rdx], 0\n\ jne .loop_{current_loop}_start\n\ .loop_{current_loop}_end:\n", )); } } } // exit syscall output.push_str( "mov rax, 60\n\ mov rdi, 0\n\ syscall\n", ); output }