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:
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user