diff options
author | Ben Bridle <ben@derelict.engineering> | 2025-10-13 13:26:10 +1300 |
---|---|---|
committer | Ben Bridle <ben@derelict.engineering> | 2025-10-13 13:26:10 +1300 |
commit | 343a15b77ece1674ca49719f04b6189bb26d220e (patch) | |
tree | c4a8869ccbb9866b49a862c93175c966150e77f3 /src | |
parent | e2a04d00ce7d989335cd678213d90134fefe0b0f (diff) | |
download | torque-asm-343a15b77ece1674ca49719f04b6189bb26d220e.zip |
Add a specific error for nested macro definitions
This case was previously being reported with the message "The macro
definition was not terminated, add a ';' character to terminate", which
was not very helpful.
Diffstat (limited to 'src')
-rw-r--r-- | src/stages/syntactic.rs | 13 | ||||
-rw-r--r-- | src/stages/syntactic_tokens.rs | 3 |
2 files changed, 11 insertions, 5 deletions
diff --git a/src/stages/syntactic.rs b/src/stages/syntactic.rs index a1ba833..227b399 100644 --- a/src/stages/syntactic.rs +++ b/src/stages/syntactic.rs @@ -4,10 +4,10 @@ use assembler::Tokeniser; pub fn parse_syntactic<P: Into<PathBuf>>(source_code: &str, path: Option<P>) -> Result<Vec<Tracked<SyntacticToken>>, Vec<Tracked<SyntacticError>>> { - parse_syntactic_from_tokeniser(Tokeniser::new(source_code, path)) + parse_syntactic_from_tokeniser(Tokeniser::new(source_code, path), false) } -fn parse_syntactic_from_tokeniser(mut t: Tokeniser) -> Result<Vec<Tracked<SyntacticToken>>, Vec<Tracked<SyntacticError>>> { +fn parse_syntactic_from_tokeniser(mut t: Tokeniser, in_macro: bool) -> Result<Vec<Tracked<SyntacticToken>>, Vec<Tracked<SyntacticError>>> { t.add_delimiters(&['@','&','%',';',':','|','{','}','(',')','[',']','#','~','"','\'']); let mut tokens = Vec::new(); let mut errors = Vec::new(); @@ -77,7 +77,7 @@ fn parse_syntactic_from_tokeniser(mut t: Tokeniser) -> Result<Vec<Tracked<Syntac t.mark_child(); if let Some(_) = t.track_until(is_matching!('{','}')) { let child = t.tokenise_child_span(); - match parse_syntactic_from_tokeniser(child) { + match parse_syntactic_from_tokeniser(child, in_macro) { Ok(tokens) => SyntacticToken::BlockLiteral(tokens), Err(mut parse_errors) => { errors.append(&mut parse_errors); @@ -93,7 +93,7 @@ fn parse_syntactic_from_tokeniser(mut t: Tokeniser) -> Result<Vec<Tracked<Syntac t.mark_child(); if let Some(_) = t.track_until(is_matching!('[',']')) { let child = t.tokenise_child_span(); - match parse_syntactic_from_tokeniser(child) { + match parse_syntactic_from_tokeniser(child, in_macro) { Ok(tokens) => SyntacticToken::Expression(tokens), Err(mut parse_errors) => { errors.append(&mut parse_errors); @@ -121,11 +121,14 @@ fn parse_syntactic_from_tokeniser(mut t: Tokeniser) -> Result<Vec<Tracked<Syntac } '%' => { let name = t.eat_token(); + if in_macro { + err!(SyntacticError::MacroDefinitionInMacroDefinition); + } let source = t.get_source(); t.mark_child(); if let Some(_) = t.track_until(is_any!(';')) { let child = t.tokenise_child_span(); - match parse_syntactic_from_tokeniser(child) { + match parse_syntactic_from_tokeniser(child, true) { Ok(body) => { let name = Tracked::from(name, source); let definition = SyntacticMacroDefinition { name, body }; diff --git a/src/stages/syntactic_tokens.rs b/src/stages/syntactic_tokens.rs index 5a0ac9e..1f8db7f 100644 --- a/src/stages/syntactic_tokens.rs +++ b/src/stages/syntactic_tokens.rs @@ -57,6 +57,7 @@ pub enum SyntacticError { UnterminatedCharacterLiteral, UnterminatedStringLiteral, UnterminatedMacroDefinition(String), + MacroDefinitionInMacroDefinition, UnmatchedBlockTerminator, UnmatchedExpressionTerminator, @@ -96,6 +97,8 @@ fn report_syntactic_error(error: &Tracked<SyntacticError>, source_code: &str) { "String was not terminated, add a '\"' character to terminate", SyntacticError::UnterminatedMacroDefinition(name) => &format!("The '{name}' macro definition was not terminated, add a ';' character to terminate"), + SyntacticError::MacroDefinitionInMacroDefinition => + &format!("Attempted to define a macro inside another macro definition"), SyntacticError::UnmatchedBlockTerminator => "Attempted to terminate a block, but no block was in progress", |