diff options
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", |