diff options
author | Ben Bridle <bridle.benjamin@gmail.com> | 2023-12-19 18:46:41 +1300 |
---|---|---|
committer | Ben Bridle <bridle.benjamin@gmail.com> | 2023-12-19 18:46:49 +1300 |
commit | 5e83592b5d5a50fb36f128980a08d04fdae3bd5f (patch) | |
tree | 025656107591d1b6c53f5c2a744b36099dcca27a /src | |
parent | 360a13ad170a8eb52cf125749129168581ace7fe (diff) | |
download | bedrock-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.
Diffstat (limited to 'src')
-rw-r--r-- | src/assembler.rs | 11 | ||||
-rw-r--r-- | src/semantic_token.rs | 7 |
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!(); |