Refactor MacroRegistry to use Rc<MacroMap>

This change introduces Rc<MacroMap> to allow for copy-on-write semantics
when defining macros in nested scopes. When a macro is defined in a
scope that is already shared, the MacroMap is cloned before
modification, ensuring that changes to one scope do not affect others
that share the same map.
This commit is contained in:
Michael Schimmel
2026-03-03 15:55:55 +01:00
parent 078b520c37
commit 78c36cf08d
+6 -4
View File
@@ -24,7 +24,7 @@ type MacroMap = HashMap<Rc<str>, (Vec<Rc<str>>, Node<UntypedKind>)>;
/// A registry for macro declarations.
#[derive(Clone)]
pub struct MacroRegistry {
scopes: Vec<MacroMap>,
scopes: Vec<Rc<MacroMap>>,
}
impl Default for MacroRegistry {
@@ -36,12 +36,12 @@ impl Default for MacroRegistry {
impl MacroRegistry {
pub fn new() -> Self {
Self {
scopes: vec![HashMap::new()],
scopes: vec![Rc::new(HashMap::new())],
}
}
pub fn push(&mut self) {
self.scopes.push(HashMap::new());
self.scopes.push(Rc::new(HashMap::new()));
}
pub fn pop(&mut self) {
@@ -51,7 +51,9 @@ impl MacroRegistry {
}
pub fn define(&mut self, name: Rc<str>, params: Vec<Rc<str>>, body: Node<UntypedKind>) {
if let Some(current) = self.scopes.last_mut() {
if let Some(current_rc) = self.scopes.last_mut() {
// Copy-on-Write: If the Rc is shared, clone the map before modifying.
let current = Rc::make_mut(current_rc);
current.insert(name, (params, body));
}
}