From 8b1c270910fce13077864bf39d6e88971a6eb062 Mon Sep 17 00:00:00 2001 From: Miquel Sabaté Solà Date: Wed, 8 Jan 2025 12:34:47 +0100 Subject: Implement the .include statement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This needed some heavy lifting when it comes to how files were located. This means that statements like .include/.incbin now take into consideration a new list made out of SourceInfo, which holds enough information to translate from which file a node comes from. This has also been added into errors, so they are more informative on what went wrong. In order to tests this, besides all the regular unit tests, a new e2e test has been added. Signed-off-by: Miquel Sabaté Solà --- lib/xixanta/src/errors.rs | 61 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 5 deletions(-) (limited to 'lib/xixanta/src/errors.rs') diff --git a/lib/xixanta/src/errors.rs b/lib/xixanta/src/errors.rs index ae55b83..3ca00bc 100644 --- a/lib/xixanta/src/errors.rs +++ b/lib/xixanta/src/errors.rs @@ -1,3 +1,4 @@ +use crate::SourceInfo; use std::fmt; #[derive(Debug, Clone, PartialEq)] @@ -7,6 +8,18 @@ pub enum Error { Eval(EvalError), } +impl From for Vec { + fn from(err: ParseError) -> Self { + vec![Error::Parse(err)] + } +} + +impl From for Vec { + fn from(err: ParseError) -> Self { + vec![err] + } +} + impl From for Vec { fn from(err: ContextError) -> Self { vec![Error::Context(err)] @@ -33,13 +46,24 @@ impl fmt::Display for Error { pub struct ParseError { pub line: usize, pub message: String, + pub source: SourceInfo, } impl std::error::Error for ParseError {} impl fmt::Display for ParseError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} (line {})", self.message, self.line + 1) + if self.source.name.is_empty() { + write!(f, "{} (line {})", self.message, self.line + 1) + } else { + write!( + f, + "{} ({}: line {})", + self.message, + self.source.name, + self.line + 1 + ) + } } } @@ -61,6 +85,7 @@ pub struct ContextError { pub reason: ContextErrorReason, pub message: String, pub global: bool, + pub source: SourceInfo, } impl std::error::Error for ContextError {} @@ -68,9 +93,21 @@ impl std::error::Error for ContextError {} impl fmt::Display for ContextError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.global { - write!(f, "{}", self.message) - } else { + if self.source.name.is_empty() { + write!(f, "{}", self.message) + } else { + write!(f, "{} ({})", self.message, self.source.name) + } + } else if self.source.name.is_empty() { write!(f, "{} (line {})", self.message, self.line + 1) + } else { + write!( + f, + "{} ({}: line {})", + self.message, + self.source.name, + self.line + 1 + ) } } } @@ -80,6 +117,7 @@ pub struct EvalError { pub line: usize, pub message: String, pub global: bool, + pub source: SourceInfo, } impl std::error::Error for EvalError {} @@ -90,6 +128,7 @@ impl From for EvalError { line: err.line, message: err.message, global: false, + source: SourceInfo::default(), // TODO } } } @@ -97,9 +136,21 @@ impl From for EvalError { impl fmt::Display for EvalError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.global { - write!(f, "{}", self.message) - } else { + if self.source.name.is_empty() { + write!(f, "{}", self.message) + } else { + write!(f, "{} ({})", self.message, self.source.name) + } + } else if self.source.name.is_empty() { write!(f, "{} (line {})", self.message, self.line + 1) + } else { + write!( + f, + "{} ({}: line {})", + self.message, + self.source.name, + self.line + 1 + ) } } } -- cgit v1.2.3