diff --git a/src/main.rs b/src/main.rs index 0ab0a8b..1046d9f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,7 @@ use std::{fs::File, io::BufRead}; use clap::Parser as ArgParser; use crate::{frontend::{lexer::Lexer, parser::Parser}, ir::generator::Generator}; - +use crate::backend::generator::Generator as ASMGerenerator; /// Simple minic compiler built by Rust #[derive(ArgParser, Debug)] #[command(version, about, long_about = None)] @@ -19,6 +19,10 @@ struct Args { /// Output the generated IR code #[arg(short = 'I', long = "ir")] output_ir: bool, + #[arg(skip)] + output_asm: bool, + #[arg(short = 't', long = "target", default_value = "ARM32")] + target: String, /// Use recursive descent parsing #[arg(short = 'D', long = "recursive-descent")] recursive_descent: bool, @@ -33,15 +37,18 @@ struct Args { } fn main() { - let args = Args::parse(); + let mut args = Args::parse(); if !args.output_ir { - eprintln!("Currently only IR generation is supported. Use -I to enable it."); - return; + args.output_asm = true; } if !args.recursive_descent { eprintln!("Currently only recursive descent parsing is supported. Use -D to enable it."); return; } + if args.target != "ARM32" { + eprintln!("Currently only ARM32 assembly output is supported. Use -t ARM32 to specify the target architecture."); + return; + } let source_path = std::path::Path::new(&args.source); let file = match File::open(&args.source) { Ok(f) => f, @@ -76,14 +83,28 @@ fn main() { if !generator.get_diagnostics().is_empty() { generator.get_diagnostics().print(&format!("{}", source_path.display()), &full_text); } - if let Some(output_path) = args.output { - match std::fs::write(&output_path, ir.iter().map(|instr| instr.to_string()).collect::>().join("\n")) { - Ok(_) => println!("IR code written to {}", output_path), - Err(e) => eprintln!("Failed to write IR code to {}: {}", output_path, e), + if args.output_ir { + if let Some(output_path) = args.output { + match std::fs::write(&output_path, ir.iter().map(|instr| instr.to_string()).collect::>().join("\n")) { + Ok(_) => println!("IR code written to {}", output_path), + Err(e) => eprintln!("Failed to write IR code to {}: {}", output_path, e), + } + } else { + for instr in ir { + println!("{}", instr); + } } - } else { - for instr in ir { - println!("{}", instr); + } else if args.output_asm { + let mut asm_generator = ASMGerenerator::new(); + asm_generator.emit(ir); + let asm_text = asm_generator.to_text(); + if let Some(output_path) = args.output { + match std::fs::write(&output_path, asm_text) { + Ok(_) => println!("Assembly code written to {}", output_path), + Err(e) => eprintln!("Failed to write assembly code to {}: {}", output_path, e), + } + } else { + println!("{}", asm_text); } } }