3 Commits

7 changed files with 65 additions and 21 deletions
+4
View File
@@ -5,3 +5,7 @@ rustc-wrapper = "sccache"
[future-incompat-report] [future-incompat-report]
frequency = "always" frequency = "always"
[profile.profiling]
inherits = "release"
debug = true
+6 -2
View File
@@ -11,7 +11,11 @@ authors = ["zxq5", "nullndvoid"]
[profile.dev] [profile.dev]
codegen-backend = "cranelift" codegen-backend = "cranelift"
panic = "abort" # Cranelift does not support stack unwinds. panic = "abort" # Cranelift does not support stack unwinds.
lto = false lto = false
debug = true debug = true
incremental = false # sccache does not support caching incremental crates. incremental = false # sccache does not support caching incremental crates.
[profile.release]
incremental = true
lto = "fat"
+17 -8
View File
@@ -13,6 +13,9 @@ pub struct AssembleError {
source_info: Option<SourceInfo>, source_info: Option<SourceInfo>,
/// The type of assembly error that occurred. /// The type of assembly error that occurred.
kind: AssembleErrorKind, 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 { impl AssembleError {
@@ -24,6 +27,7 @@ impl AssembleError {
Self { Self {
source_info: Some(source_info), source_info: Some(source_info),
kind, kind,
display_quietly: false,
} }
} }
@@ -32,6 +36,7 @@ impl AssembleError {
Self { Self {
source_info: None, source_info: None,
kind, kind,
display_quietly: true,
} }
} }
@@ -44,20 +49,22 @@ impl AssembleError {
let Some(source_info) = &self.source_info else { let Some(source_info) = &self.source_info else {
write!( write!(
f, f,
"Parse error thrown with no source information. Error: {parse_error}" "parser error thrown with no source information. Error: {parse_error}"
)?; )?;
return Ok(()); 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. // Prints out the context for our error.
source_info.print_context_with_underline().map_err(|e| { if !self.display_quietly {
_ = writeln!(f, "Print context error: {e}"); source_info.print_context_with_underline().map_err(|e| {
_ = writeln!(f, "print context error: {e}");
std::fmt::Error {} std::fmt::Error {}
})?; })?;
}
Ok(()) Ok(())
} }
@@ -77,7 +84,7 @@ impl AssembleError {
return Ok(()); 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. // Prints out the context for our error.
source_info.print_context_with_underline().map_err(|e| { source_info.print_context_with_underline().map_err(|e| {
@@ -93,7 +100,7 @@ impl AssembleError {
impl Display for AssembleError { impl Display for AssembleError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(info) = &self.source_info { if let Some(info) = &self.source_info {
write!(f, "at {info}")?; write!(f, "At {info}, got ")?;
match &self.kind { match &self.kind {
AssembleErrorKind::Parser(err) => self.print_parser_error(f, err)?, AssembleErrorKind::Parser(err) => self.print_parser_error(f, err)?,
@@ -103,6 +110,8 @@ impl Display for AssembleError {
_ => write!(f, "{}", self.kind)?, _ => write!(f, "{}", self.kind)?,
} }
writeln!(f)?;
return Ok(()); return Ok(());
} }
+30 -1
View File
@@ -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 common as _;
use num_cpus as _; use num_cpus as _;
use threadpool as _; use threadpool as _;
@@ -5,9 +12,31 @@ use threadpool as _;
// use clap::Parser; // use clap::Parser;
// use std::{fs, io::Write, path::PathBuf}; // use std::{fs, io::Write, path::PathBuf};
fn main() { fn main() -> Result<(), AssembleError> {
// // Parse command line arguments // // Parse command line arguments
// let args: Vec<String> = std::env::args().collect(); // let args: Vec<String> = 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(); // let _clap_args = assembler::args::Args::parse();
+7 -5
View File
@@ -32,10 +32,10 @@ impl Display for SourceInfo {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!( write!(
f, f,
"{}:{}, column {}", "{}:{}:{}",
self.module.path.display(), self.module.path.display(),
self.line_number, self.line_number,
self.span.start self.span.start + 1
) )
} }
} }
@@ -82,11 +82,13 @@ impl SourceInfo {
// Print the line number and line content. // Print the line number and line content.
println!("{:>4} | {}", self.line_number, line_span.content); println!("{:>4} | {}", self.line_number, line_span.content);
let mut pad_left = String::new();
write!(pad_left, "{:>4} ", "")?;
let mut underline = String::new(); let mut underline = String::new();
write!(underline, "{:>4} | ", "")?;
for _ in 0..self.span.start { for _ in 0..self.span.start {
underline.push(' '); pad_left.push(' ');
} }
for _ in self.span.start..self.span.end.min(line_span.content.len()) { 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. // Print the underline in red and bold.
// TODO: Use a crate to make this extra portable. // 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(()) Ok(())
} }
-4
View File
@@ -234,8 +234,6 @@ impl Tokeniser {
// Remove any underscores that were inserted for readability. // Remove any underscores that were inserted for readability.
let value_str = value_str.replace('_', ""); let value_str = value_str.replace('_', "");
dbg!(&value_str);
let value = if let Some(hex_part) = value_str.strip_prefix("0x") { let value = if let Some(hex_part) = value_str.strip_prefix("0x") {
u32::from_str_radix(hex_part, 16).ok()? u32::from_str_radix(hex_part, 16).ok()?
} else if let Some(bin_part) = value_str.strip_prefix("0b") { } else if let Some(bin_part) = value_str.strip_prefix("0b") {
@@ -361,8 +359,6 @@ impl Tokeniser {
line_number: usize, line_number: usize,
column: usize, column: usize,
) -> Result<(TokenType, usize), AssembleError> { ) -> Result<(TokenType, usize), AssembleError> {
dbg!(input);
if input.starts_with(',') { if input.starts_with(',') {
return Ok((TokenType::Comma, 1)); return Ok((TokenType::Comma, 1));
} }
+1 -1
View File
@@ -40,7 +40,7 @@ impl std::fmt::Display for InstructionDecodeError {
match self { match self {
Self::InvalidOpcode(code) => write!(f, "invalid opcode, got {code:x}")?, Self::InvalidOpcode(code) => write!(f, "invalid opcode, got {code:x}")?,
Self::InvalidArgument(err) => { Self::InvalidArgument(err) => {
write!(f, "invalid arguments, got an error {err}")? write!(f, "invalid arguments, got an error {err}")?;
} }
} }