compile assembly

This commit is contained in:
2025-05-29 19:12:57 +02:00
parent 4d066acda3
commit f0938ce0a3
2 changed files with 72 additions and 19 deletions

View File

@@ -14,24 +14,34 @@ impl Codegen {
} }
pub fn emit_prologue(&mut self) -> Result<(), Box<dyn Error>> { pub fn emit_prologue(&mut self) -> Result<(), Box<dyn Error>> {
writeln!(&mut self.output, "section .data")?; writeln!(
writeln!(&mut self.output, "format db \"%d\", 10, 0")?; &mut self.output,
writeln!(&mut self.output, "section .text")?; "section .data
writeln!(&mut self.output, "global main")?; format db \"%d\", 10, 0
writeln!(&mut self.output, "main:")?; section .text
writeln!(&mut self.output, " extern printf")?; global main
main:
extern printf"
)?;
Ok(()) Ok(())
} }
pub fn emit_epilogue(&mut self) -> Result<(), Box<dyn Error>> { pub fn emit_epilogue(&mut self) -> Result<(), Box<dyn Error>> {
writeln!(&mut self.output, " mov rdi, format")?; write!(
writeln!(&mut self.output, " mov rsi, rax")?; &mut self.output,
writeln!(&mut self.output, " xor rax, rax")?; "
writeln!(&mut self.output, " call printf")?; mov rdi, format
writeln!(&mut self.output, " mov rax, 0")?; mov rsi, rax
writeln!(&mut self.output, " ret")?; xor rax, rax
writeln!(&mut self.output, "section .note.GNU-stack")?; call printf
writeln!(&mut self.output, " db 0")?;
mov rax, 0
ret
section .note.GNU-stack
db 0
"
)?;
Ok(()) Ok(())
} }
@@ -56,15 +66,37 @@ impl Codegen {
writeln!(&mut self.output, " cqo")?; writeln!(&mut self.output, " cqo")?;
writeln!(&mut self.output, " idiv rbx")?; 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::Grouping(expr) => self.compile_expr(*expr)?,
Expr::Literal(token) => match token.token_type { Expr::Literal(token) => match token.token_type {
TokenType::Number => writeln!(&mut self.output, " mov rax, {}", token.lexeme)?, 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(()) Ok(())
} }

View File

@@ -2,7 +2,12 @@ mod codegen;
mod parser; mod parser;
mod tokenizer; 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<dyn Error>> { fn compile_file(path: String) -> Result<(), Box<dyn Error>> {
let source = fs::read_to_string(path.clone())?; let source = fs::read_to_string(path.clone())?;
@@ -18,7 +23,23 @@ fn compile_file(path: String) -> Result<(), Box<dyn Error>> {
codegen.emit_prologue()?; codegen.emit_prologue()?;
codegen.compile_expr(expr)?; codegen.compile_expr(expr)?;
codegen.emit_epilogue()?; 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(()) Ok(())
} }