diff options
author | Ben Bridle <ben@derelict.engineering> | 2025-03-25 11:52:25 +1300 |
---|---|---|
committer | Ben Bridle <ben@derelict.engineering> | 2025-03-25 11:52:25 +1300 |
commit | fa6e20f118542cc8852590a5215e98bf585164db (patch) | |
tree | 4a12e25499c2f3d98c09a0fe3f0dab98562a4f59 | |
parent | d4ef2eed48be4e99f50b51ab57096c9b3532b7a1 (diff) | |
download | bedrock-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.rs | 14 |
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) } |