diff options
-rw-r--r-- | src/stages/intermediate.rs | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/src/stages/intermediate.rs b/src/stages/intermediate.rs index 6853f62..ca17aa0 100644 --- a/src/stages/intermediate.rs +++ b/src/stages/intermediate.rs @@ -88,6 +88,16 @@ impl IntermediateParser { let tracked = Tracked::from(value, null.clone()); arguments.insert(argument.name.clone(), tracked); } + // Register macro definition with empty body so that macro can invoke itself. + let name = definition.name.to_string(); + let dummy_definition = MacroDefinition { + name: definition.name, + arguments: definition.arguments, + body: MacroDefinitionBody::Block(Vec::new()), + }; + if self.macro_definitions.insert(name.clone(), dummy_definition).is_some() { + unreachable!("Uncaught duplicate macro definition '{}'", name); + } let mut env = Environment { label_names: &self.label_names, macro_names: &self.macro_names, @@ -100,10 +110,9 @@ impl IntermediateParser { if self.errors.len() != error_count { break; } - - let name = definition.name.to_string(); - if self.macro_definitions.insert(name.clone(), definition).is_some() { - unreachable!("Uncaught duplicate macro definition '{}'", name); + // Replace dummy macro body with original macro body. + if let Some(registered) = self.macro_definitions.get_mut(&name) { + registered.body = definition.body; } } SemanticToken::BlockToken(block_token) => { |