From f3c6b02fb2f2957b9b896c34d05abe75263c3f60 Mon Sep 17 00:00:00 2001 From: Miquel Sabaté Solà Date: Sun, 5 Jan 2025 16:34:52 +0100 Subject: Store a reference for macros instead of an index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is not safe to store a node index for macros since the list of nodes that is passed down during assembly might change depending on whether an inner block is being evaluated. Hence, the previous implementation would break on a simple macro call inside of a .proc. This also raised some concerns on the design around the API, since the lifetime of references for internal assembler data needed an explicit lifetime now, and as a side-effect functions like `assemble` had to be moved out of the inner impl Assembler. This is in retrospect also a better design choice. Fixes: ec8b709fa24c ("Implement block bodies inside of the assembler"). Signed-off-by: Miquel Sabaté Solà --- crates/nasm/src/main.rs | 61 ++++++++++++++++++------------------------------- 1 file changed, 22 insertions(+), 39 deletions(-) (limited to 'crates/nasm') diff --git a/crates/nasm/src/main.rs b/crates/nasm/src/main.rs index 1a0ffea..225a865 100644 --- a/crates/nasm/src/main.rs +++ b/crates/nasm/src/main.rs @@ -3,8 +3,7 @@ use clap::Parser as ClapParser; use std::fs::File; use std::io::{self, Read, Write}; use std::path::Path; -use xixanta::assembler::Assembler; -use xixanta::mapping::get_mapping_configuration; +use xixanta::assembler::assemble; /// Assembler for the 6502 microprocessor that targets the NES/Famicom. #[derive(ClapParser, Debug)] @@ -80,47 +79,31 @@ fn main() -> Result<()> { // Select the linker configuration. let config = args.config.unwrap_or("nrom".to_string()); - let mapping = match get_mapping_configuration(&config) { - Ok(cfg) => cfg, - Err(e) => { - eprintln!("error: {}", e); - std::process::exit(1); - } - }; // And assemble. let mut error_count = 0; - let mut assembler = Assembler::new(mapping); - match assembler.assemble(working_directory.to_path_buf(), input) { - Ok(bundles) => { - for warning in assembler.warnings() { - if warn_as_errors { - eprintln!("error: {}", warning); - error_count += 1; - } else { - eprintln!("warning: {}", warning); - } - } - if error_count == 0 { - for b in bundles { - for i in 0..b.size { - output.write_all(&[b.bytes[i as usize]])?; - } - } - } + let res = assemble(input, config.as_str(), working_directory.to_path_buf()); + + // Print warnings and errors first, while also computing the amount of them + // that exists. + for warning in res.warnings { + if warn_as_errors { + eprintln!("error: {}", warning); + error_count += 1; + } else { + eprintln!("warning: {}", warning); } - Err(errors) => { - for warning in assembler.warnings() { - if warn_as_errors { - eprintln!("error: {}", warning); - error_count += 1; - } else { - eprintln!("warning: {}", warning); - } - } - for err in errors { - eprintln!("error: {}", err); - error_count += 1; + } + for error in res.errors { + eprintln!("error: {}", error); + error_count += 1; + } + + // If everything was right, just deliver the bundles. + if error_count == 0 { + for b in res.bundles { + for i in 0..b.size { + output.write_all(&[b.bytes[i as usize]])?; } } } -- cgit v1.2.3