From 85e3d443cc6639cee4936396eda8e6dc5bb3bbd8 Mon Sep 17 00:00:00 2001 From: "J. Hinchliffe" Date: Sun, 29 Jun 2025 03:52:53 +0100 Subject: [PATCH] assembler: small misc updates, I am tired --- assembler/src/error.rs | 25 +++++++++++++++-------- assembler/src/main.rs | 31 ++++++++++++++++++++++++++++- assembler/src/source/source_info.rs | 12 ++++++----- assembler/src/source/tokeniser.rs | 4 ---- common/src/instructions/errors.rs | 2 +- 5 files changed, 55 insertions(+), 19 deletions(-) diff --git a/assembler/src/error.rs b/assembler/src/error.rs index f8b84fe..511f598 100644 --- a/assembler/src/error.rs +++ b/assembler/src/error.rs @@ -13,6 +13,9 @@ pub struct AssembleError { source_info: Option, /// The type of assembly error that occurred. kind: AssembleErrorKind, + /// Whether context should be added to errors being printed. This might get changed + /// to Verbosity in the future. + display_quietly: bool, } impl AssembleError { @@ -24,6 +27,7 @@ impl AssembleError { Self { source_info: Some(source_info), kind, + display_quietly: false, } } @@ -32,6 +36,7 @@ impl AssembleError { Self { source_info: None, kind, + display_quietly: true, } } @@ -44,20 +49,22 @@ impl AssembleError { let Some(source_info) = &self.source_info else { write!( f, - "Parse error thrown with no source information. Error: {parse_error}" + "parser error thrown with no source information. Error: {parse_error}" )?; return Ok(()); }; - writeln!(f, "Parser error, {parse_error} at {source_info}.")?; + writeln!(f, "parser error of type `{parse_error}`.\n")?; // Prints out the context for our error. - source_info.print_context_with_underline().map_err(|e| { - _ = writeln!(f, "Print context error: {e}"); + if !self.display_quietly { + source_info.print_context_with_underline().map_err(|e| { + _ = writeln!(f, "print context error: {e}"); - std::fmt::Error {} - })?; + std::fmt::Error {} + })?; + } Ok(()) } @@ -77,7 +84,7 @@ impl AssembleError { return Ok(()); }; - writeln!(f, "Tokeniser error, {err} at {source_info}.")?; + writeln!(f, "tokeniser error of type `{err}`.\n")?; // Prints out the context for our error. source_info.print_context_with_underline().map_err(|e| { @@ -93,7 +100,7 @@ impl AssembleError { impl Display for AssembleError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if let Some(info) = &self.source_info { - write!(f, "at {info}")?; + write!(f, "At {info}, got ")?; match &self.kind { AssembleErrorKind::Parser(err) => self.print_parser_error(f, err)?, @@ -103,6 +110,8 @@ impl Display for AssembleError { _ => write!(f, "{}", self.kind)?, } + writeln!(f)?; + return Ok(()); } diff --git a/assembler/src/main.rs b/assembler/src/main.rs index e172aa3..2fd96ac 100644 --- a/assembler/src/main.rs +++ b/assembler/src/main.rs @@ -1,3 +1,10 @@ +use std::sync::Arc; + +use assembler::{ + error::{AssembleError, AssembleErrorKind, ParserError}, + model::module::Module, + source::{source_info::SourceInfo, token::TokenType, tokeniser::Tokeniser}, +}; use common as _; use num_cpus as _; use threadpool as _; @@ -5,9 +12,31 @@ use threadpool as _; // use clap::Parser; // use std::{fs, io::Write, path::PathBuf}; -fn main() { +fn main() -> Result<(), AssembleError> { // // Parse command line arguments // let args: Vec = std::env::args().collect(); + let contents = include_bytes!("../../resources/dsa/bf.dsa").to_vec(); + + let module = Arc::new(Module::new("resources/dsa/bf.dsa")?); + let tok = Tokeniser::from_data(contents, module.clone()); + + let ts = tok + .tokenise()? + .into_iter() + .filter(|t| !matches!(t.token_type, TokenType::Eof | TokenType::Newline)); + + for t in ts { + t.source_info.print_context_with_underline()?; + } + + let test_error: AssembleError = AssembleError::new_source_error( + SourceInfo::new(45, module.clone(), 4..7), + AssembleErrorKind::Parser(ParserError::InvalidInstruction), + ); + + eprintln!("\n\n{test_error}"); + + Ok(()) // let _clap_args = assembler::args::Args::parse(); diff --git a/assembler/src/source/source_info.rs b/assembler/src/source/source_info.rs index 0071bf0..c6fd988 100644 --- a/assembler/src/source/source_info.rs +++ b/assembler/src/source/source_info.rs @@ -32,10 +32,10 @@ impl Display for SourceInfo { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, - "{}:{}, column {}", + "{}:{}:{}", self.module.path.display(), self.line_number, - self.span.start + self.span.start + 1 ) } } @@ -82,11 +82,13 @@ impl SourceInfo { // Print the line number and line content. println!("{:>4} | {}", self.line_number, line_span.content); + let mut pad_left = String::new(); + write!(pad_left, "{:>4} ", "")?; + let mut underline = String::new(); - write!(underline, "{:>4} | ", "")?; for _ in 0..self.span.start { - underline.push(' '); + pad_left.push(' '); } for _ in self.span.start..self.span.end.min(line_span.content.len()) { @@ -95,7 +97,7 @@ impl SourceInfo { // Print the underline in red and bold. // TODO: Use a crate to make this extra portable. - println!("\x1b[1;31m{underline}\x1b[0m"); + println!("{pad_left}\x1b[1;31m{underline}\x1b[0m"); Ok(()) } diff --git a/assembler/src/source/tokeniser.rs b/assembler/src/source/tokeniser.rs index d180657..5ef46b2 100644 --- a/assembler/src/source/tokeniser.rs +++ b/assembler/src/source/tokeniser.rs @@ -234,8 +234,6 @@ impl Tokeniser { // Remove any underscores that were inserted for readability. let value_str = value_str.replace('_', ""); - dbg!(&value_str); - let value = if let Some(hex_part) = value_str.strip_prefix("0x") { u32::from_str_radix(hex_part, 16).ok()? } else if let Some(bin_part) = value_str.strip_prefix("0b") { @@ -361,8 +359,6 @@ impl Tokeniser { line_number: usize, column: usize, ) -> Result<(TokenType, usize), AssembleError> { - dbg!(input); - if input.starts_with(',') { return Ok((TokenType::Comma, 1)); } diff --git a/common/src/instructions/errors.rs b/common/src/instructions/errors.rs index 995124a..04f6cfb 100644 --- a/common/src/instructions/errors.rs +++ b/common/src/instructions/errors.rs @@ -40,7 +40,7 @@ impl std::fmt::Display for InstructionDecodeError { match self { Self::InvalidOpcode(code) => write!(f, "invalid opcode, got {code:x}")?, Self::InvalidArgument(err) => { - write!(f, "invalid arguments, got an error {err}")? + write!(f, "invalid arguments, got an error {err}")?; } }