summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Bridle <bridle.benjamin@gmail.com>2023-12-19 18:46:41 +1300
committerBen Bridle <bridle.benjamin@gmail.com>2023-12-19 18:46:49 +1300
commit5e83592b5d5a50fb36f128980a08d04fdae3bd5f (patch)
tree025656107591d1b6c53f5c2a744b36099dcca27a
parent360a13ad170a8eb52cf125749129168581ace7fe (diff)
downloadbedrock-asm-5e83592b5d5a50fb36f128980a08d04fdae3bd5f.zip
Report preceding label name on assembly error
When the assembler encounters an error, the erroneous line and the line number are output in order to help the user to find where in the input file the error occurred. This is useful for single-file inputs, but the line number is generally not helpful if the input file was generated by concatenating multiple files. In order to help the user to determine where in the program source the error occurred, the assembler now reports the name of the label which directly precedes the erroneous line.
-rw-r--r--src/assembler.rs11
-rw-r--r--src/semantic_token.rs7
2 files changed, 15 insertions, 3 deletions
diff --git a/src/assembler.rs b/src/assembler.rs
index cb6b6f1..692eb14 100644
--- a/src/assembler.rs
+++ b/src/assembler.rs
@@ -78,9 +78,13 @@ impl Assembler {
pub fn resolve_references(&mut self) {
let syntactic_tokens = take(&mut self.syntactic_tokens);
let syntactic_token_count = syntactic_tokens.len();
+ let mut parent_label = None;
for (index, syntactic_token) in syntactic_tokens.into_iter().enumerate() {
- let semantic_token = self.convert_syn_token_to_sem_token(syntactic_token, index);
+ if let SyntacticTokenType::LabelDefinition(name) = &syntactic_token.r#type {
+ parent_label = Some(name.to_owned());
+ }
+ let semantic_token = self.convert_syn_token_to_sem_token(syntactic_token, index, parent_label.clone());
self.semantic_tokens.push(semantic_token);
}
assert_eq!(syntactic_token_count, self.semantic_tokens.len());
@@ -199,7 +203,7 @@ impl Assembler {
(bytecode, semantic_tokens)
}
- fn convert_syn_token_to_sem_token(&mut self, mut syn_token: SyntacticToken, index: usize) -> SemanticToken {
+ fn convert_syn_token_to_sem_token(&mut self, mut syn_token: SyntacticToken, index: usize, parent_label: Option<String>) -> SemanticToken {
SemanticToken {
r#type: {
if let Some(err) = syn_token.error {
@@ -221,7 +225,7 @@ impl Assembler {
if syn_body_token.is_macro_terminator() {
syn_token.source_location.end = syn_body_token.source_location.start;
}
- let sem_body_token = self.convert_syn_token_to_sem_token(syn_body_token, 0);
+ let sem_body_token = self.convert_syn_token_to_sem_token(syn_body_token, 0, parent_label.clone());
sem_body_tokens.push(sem_body_token);
}
self.semantic_macro_bodies.insert(index, sem_body_tokens);
@@ -238,6 +242,7 @@ impl Assembler {
},
source_location: syn_token.source_location,
bytecode_location: BytecodeLocation::zero(),
+ parent_label,
}
}
diff --git a/src/semantic_token.rs b/src/semantic_token.rs
index 77ba892..265db91 100644
--- a/src/semantic_token.rs
+++ b/src/semantic_token.rs
@@ -21,6 +21,7 @@ pub struct SemanticToken {
pub r#type: SemanticTokenType,
pub source_location: SourceLocation,
pub bytecode_location: BytecodeLocation,
+ pub parent_label: Option<String>,
}
impl SemanticToken {
@@ -28,6 +29,7 @@ impl SemanticToken {
pub fn print_error(&self, source_code: &str) -> bool {
let mut is_error = false;
macro_rules! red {()=>{eprint!("\x1b[31m")};}
+ macro_rules! dim {()=>{eprint!("\x1b[0;2m")};}
macro_rules! normal {()=>{eprint!("\x1b[0m")};}
if let SemanticTokenType::Error(token, error) = &self.r#type {
@@ -60,6 +62,11 @@ impl SemanticToken {
};
eprintln!("Invalid token in macro definition, macro definitions are not allowed to contain {name}") }
}
+
+ if let Some(label) = &self.parent_label {
+ eprint!(" ... "); red!(); eprint!("| "); dim!(); eprintln!("@{label} "); normal!();
+ }
+
let line = source_code.split('\n').nth(self.source_location.start.line).unwrap();
eprint!("{:>5} ", self.source_location.start.line+1);
red!(); eprint!("| "); normal!();