summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/stages/intermediate.rs17
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) => {