From 8d14da82c508e0ca34e22d964377195f4f3b5277 Mon Sep 17 00:00:00 2001 From: Brummel Date: Tue, 31 Mar 2026 17:11:57 +0200 Subject: [PATCH] Persist macros after expansion When expanding macros, the expander may encounter new macro declarations. These need to be stored back into the environment's macro registry so that they are available for subsequent compilation passes or other environments. Persist macros after expansion This commit modifies the `expand` method in `src/ast/environment.rs` to persist macro declarations encountered during expansion. When a macro is expanded, the `Expander` updates its internal registry. This change ensures that the updated registry is then stored back into the `Environment`'s `macro_registry`. This allows subsequent compilations or expansions within the same environment to correctly recognize and utilize these newly defined macros. Additionally, a `NodeKind::Program` case was added to the `CapturePass::transform` method in `src/ast/compiler/captures.rs`. This ensures that expressions within a program node are also recursively transformed, maintaining consistency in the AST processing pipeline. --- src/ast/compiler/captures.rs | 7 +++++++ src/ast/environment.rs | 10 ++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/ast/compiler/captures.rs b/src/ast/compiler/captures.rs index a815762..f3cdcaa 100644 --- a/src/ast/compiler/captures.rs +++ b/src/ast/compiler/captures.rs @@ -70,6 +70,13 @@ impl CapturePass { .collect(), }, + NodeKind::Program { exprs } => NodeKind::Program { + exprs: exprs + .into_iter() + .map(|e| Rc::new(Self::transform(e.as_ref().clone(), capture_map))) + .collect(), + }, + NodeKind::Tuple { elements } => NodeKind::Tuple { elements: elements .into_iter() diff --git a/src/ast/environment.rs b/src/ast/environment.rs index 8ea961f..90f285a 100644 --- a/src/ast/environment.rs +++ b/src/ast/environment.rs @@ -390,9 +390,15 @@ impl Environment { } /// Expands macros in a syntax AST. + /// Any macro declarations encountered during expansion are persisted back + /// into the environment's registry so subsequent compilations can use them. fn expand(&self, syntax_ast: SyntaxNode, diagnostics: &mut Diagnostics) -> Option { - match self.get_expander().expand(syntax_ast) { - Ok(ast) => Some(ast), + let mut expander = self.get_expander(); + match expander.expand(syntax_ast) { + Ok(ast) => { + *self.macro_registry.borrow_mut() = expander.into_registry(); + Some(ast) + } Err(e) => { diagnostics.push_error(e, None); None