summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Bridle <ben@derelict.engineering>2025-03-25 11:52:25 +1300
committerBen Bridle <ben@derelict.engineering>2025-03-25 11:52:25 +1300
commitfa6e20f118542cc8852590a5215e98bf585164db (patch)
tree4a12e25499c2f3d98c09a0fe3f0dab98562a4f59
parentd4ef2eed48be4e99f50b51ab57096c9b3532b7a1 (diff)
downloadbedrock-asm-fa6e20f118542cc8852590a5215e98bf585164db.zip
Improve error reporting for macros invoked before definition
These errors were only being correctly reported when the invocation was inside a macro body. The error report has been expanded to also report the location of the eventual matching macro definition.
-rw-r--r--src/stages/semantic.rs14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/stages/semantic.rs b/src/stages/semantic.rs
index da804ec..8b5f4f4 100644
--- a/src/stages/semantic.rs
+++ b/src/stages/semantic.rs
@@ -64,9 +64,10 @@ pub fn parse_semantic(syntactic: Vec<Tracked<SyntacticToken>>) -> Result<Program
SyntacticToken::Invocation(symbol) => {
if let Some(definition) = definitions.get_mut(&symbol) {
definition.value.deep_references.push((i, j));
- } else if macro_names.contains(&symbol) {
+ } else if let Some(definition) = macro_names.get(&symbol) {
let error = SemanticError::InvocationBeforeDefinition;
- errors.push(Tracked::from(error, syn_token.source.clone()));
+ let source = syn_token.source.wrap(definition.source.clone());
+ errors.push(Tracked::from(error, source));
} else {
unreachable!("Uncaught undefined symbol '{symbol}'");
};
@@ -106,10 +107,15 @@ pub fn parse_semantic(syntactic: Vec<Tracked<SyntacticToken>>) -> Result<Program
SyntacticToken::RawValue(value) => SemanticToken::RawValue(value),
SyntacticToken::Instruction(instruction) => SemanticToken::Instruction(instruction),
SyntacticToken::Invocation(symbol) => {
- let Some(definition) = definitions.get_mut(&symbol) else {
+ if let Some(definition) = definitions.get_mut(&symbol) {
+ definition.value.references.push(i);
+ } else if let Some(definition) = macro_names.get(&symbol) {
+ let error = SemanticError::InvocationBeforeDefinition;
+ let source = syn_token.source.wrap(definition.source.clone());
+ errors.push(Tracked::from(error, source));
+ } else {
unreachable!("Uncaught undefined symbol '{symbol}'");
};
- definition.value.references.push(i);
SemanticToken::Invocation(symbol)
}