From f0938ce0a3e5262a51cdae20911ad96a0a63c3a9 Mon Sep 17 00:00:00 2001 From: Toni Date: Thu, 29 May 2025 19:12:57 +0200 Subject: [PATCH] compile assembly --- src/codegen.rs | 66 +++++++++++++++++++++++++++++++++++++------------- src/main.rs | 25 +++++++++++++++++-- 2 files changed, 72 insertions(+), 19 deletions(-) diff --git a/src/codegen.rs b/src/codegen.rs index 53189aa..e49aa8d 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -14,24 +14,34 @@ impl Codegen { } pub fn emit_prologue(&mut self) -> Result<(), Box> { - writeln!(&mut self.output, "section .data")?; - writeln!(&mut self.output, "format db \"%d\", 10, 0")?; - writeln!(&mut self.output, "section .text")?; - writeln!(&mut self.output, "global main")?; - writeln!(&mut self.output, "main:")?; - writeln!(&mut self.output, " extern printf")?; + writeln!( + &mut self.output, + "section .data +format db \"%d\", 10, 0 +section .text +global main +main: + extern printf" + )?; Ok(()) } pub fn emit_epilogue(&mut self) -> Result<(), Box> { - writeln!(&mut self.output, " mov rdi, format")?; - writeln!(&mut self.output, " mov rsi, rax")?; - writeln!(&mut self.output, " xor rax, rax")?; - writeln!(&mut self.output, " call printf")?; - writeln!(&mut self.output, " mov rax, 0")?; - writeln!(&mut self.output, " ret")?; - writeln!(&mut self.output, "section .note.GNU-stack")?; - writeln!(&mut self.output, " db 0")?; + write!( + &mut self.output, + " + mov rdi, format + mov rsi, rax + xor rax, rax + call printf + + mov rax, 0 + ret + +section .note.GNU-stack + db 0 +" + )?; Ok(()) } @@ -56,15 +66,37 @@ impl Codegen { writeln!(&mut self.output, " cqo")?; writeln!(&mut self.output, " idiv rbx")?; } - _ => todo!(), + TokenType::Mod => { + writeln!(&mut self.output, " cqo")?; + writeln!(&mut self.output, " idiv rbx")?; + writeln!(&mut self.output, " mov rax, rdx")?; + } + TokenType::Xor => writeln!(&mut self.output, " xor rax, rbx")?, + TokenType::And => todo!(), + TokenType::Or => todo!(), + TokenType::DoubleEqual => todo!(), + TokenType::NotEqual => todo!(), + TokenType::Greater => todo!(), + TokenType::GreaterEqual => todo!(), + TokenType::Less => todo!(), + TokenType::LessEqual => todo!(), + _ => unreachable!(), } } Expr::Grouping(expr) => self.compile_expr(*expr)?, Expr::Literal(token) => match token.token_type { TokenType::Number => writeln!(&mut self.output, " mov rax, {}", token.lexeme)?, - _ => todo!(), + TokenType::String => todo!(), + _ => unreachable!(), }, - Expr::Unary { op, right } => todo!(), + Expr::Unary { op, right } => { + self.compile_expr(*right)?; + match op.token_type { + TokenType::Minus => writeln!(&mut self.output, " neg rax")?, + TokenType::Bang => todo!(), + _ => unreachable!(), + } + } } Ok(()) } diff --git a/src/main.rs b/src/main.rs index 13e8d2b..6aa37b0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,12 @@ mod codegen; mod parser; mod tokenizer; -use std::{env, error::Error, fs, process}; +use std::{ + env, + error::Error, + fs, + process::{self, Command}, +}; fn compile_file(path: String) -> Result<(), Box> { let source = fs::read_to_string(path.clone())?; @@ -18,7 +23,23 @@ fn compile_file(path: String) -> Result<(), Box> { codegen.emit_prologue()?; codegen.compile_expr(expr)?; codegen.emit_epilogue()?; - println!("{}", codegen.get_output()); + + fs::write("out.s", codegen.get_output())?; + Command::new("nasm") + .args(["-f", "elf64", "-o", "out.o", "out.s"]) + .output()?; + + Command::new("ld") + .args([ + "-dynamic-linker", + "/lib64/ld-linux-x86-64.so.2", + "-lc", + "/usr/lib/x86_64-linux-gnu/crt1.o", + "-o", + "out", + "out.o", + ]) + .output()?; Ok(()) }