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 /src | |
| 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.
Diffstat (limited to 'src')
| -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)              } | 
