Refactor AST nodes to use Rc
This commit refactors various AST node types to use `Rc` (Reference Counting) instead of `Box`. This change is primarily driven by the need for shared ownership and more efficient handling of potentially recursive or shared data structures within the AST. The main benefits of this change include: - **Reduced cloning:** `Rc` allows multiple parts of the AST to refer to the same node without needing to clone the entire node. This is particularly beneficial for optimization passes where nodes might be visited multiple times. - **Enabling sharing:** It makes it easier to represent scenarios where a single AST node might be a child of multiple parent nodes. - **Performance improvements:** By avoiding unnecessary deep copies of AST nodes, this change can lead to performance gains, especially during complex compilation phases.
This commit is contained in:
@@ -54,7 +54,7 @@ impl<T> Clone for Box<dyn BoundExtension<T>> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Type alias for a node that has been bound. Defaults to untyped (T = ()).
|
||||
/// A bound AST node, decorated with type or metric information T.
|
||||
pub type BoundNode<T = ()> = Node<BoundKind<T>, T>;
|
||||
|
||||
/// Type alias for a node that has been fully type-checked.
|
||||
@@ -91,7 +91,7 @@ pub enum BoundKind<T = ()> {
|
||||
// Variable Update (Assignment)
|
||||
Set {
|
||||
addr: Address,
|
||||
value: Box<BoundNode<T>>,
|
||||
value: Rc<BoundNode<T>>,
|
||||
},
|
||||
|
||||
// Variable Declaration (Unified for Local/Global/Parameter)
|
||||
@@ -99,7 +99,7 @@ pub enum BoundKind<T = ()> {
|
||||
name: Symbol,
|
||||
addr: Address,
|
||||
kind: DeclarationKind,
|
||||
value: Box<BoundNode<T>>,
|
||||
value: Rc<BoundNode<T>>,
|
||||
captured_by: Vec<Identity>,
|
||||
},
|
||||
|
||||
@@ -108,20 +108,20 @@ pub enum BoundKind<T = ()> {
|
||||
|
||||
/// Specialized field access (O(1) via RecordLayout)
|
||||
GetField {
|
||||
rec: Box<BoundNode<T>>,
|
||||
rec: Rc<BoundNode<T>>,
|
||||
field: crate::ast::types::Keyword,
|
||||
},
|
||||
|
||||
If {
|
||||
cond: Box<BoundNode<T>>,
|
||||
then_br: Box<BoundNode<T>>,
|
||||
else_br: Option<Box<BoundNode<T>>>,
|
||||
cond: Rc<BoundNode<T>>,
|
||||
then_br: Rc<BoundNode<T>>,
|
||||
else_br: Option<Rc<BoundNode<T>>>,
|
||||
},
|
||||
|
||||
/// A destructuring operation (can be a definition or an assignment depending on the pattern)
|
||||
Destructure {
|
||||
pattern: Box<BoundNode<T>>,
|
||||
value: Box<BoundNode<T>>,
|
||||
pattern: Rc<BoundNode<T>>,
|
||||
value: Rc<BoundNode<T>>,
|
||||
},
|
||||
|
||||
Lambda {
|
||||
@@ -134,29 +134,29 @@ pub enum BoundKind<T = ()> {
|
||||
},
|
||||
|
||||
Call {
|
||||
callee: Box<BoundNode<T>>,
|
||||
args: Box<BoundNode<T>>,
|
||||
callee: Rc<BoundNode<T>>,
|
||||
args: Rc<BoundNode<T>>,
|
||||
},
|
||||
|
||||
Again {
|
||||
args: Box<BoundNode<T>>,
|
||||
args: Rc<BoundNode<T>>,
|
||||
},
|
||||
Pipe {
|
||||
inputs: Vec<BoundNode<T>>,
|
||||
lambda: Box<BoundNode<T>>,
|
||||
inputs: Vec<Rc<BoundNode<T>>>,
|
||||
lambda: Rc<BoundNode<T>>,
|
||||
out_type: crate::ast::types::StaticType,
|
||||
},
|
||||
Block {
|
||||
exprs: Vec<BoundNode<T>>,
|
||||
exprs: Vec<Rc<BoundNode<T>>>,
|
||||
},
|
||||
|
||||
Tuple {
|
||||
elements: Vec<BoundNode<T>>,
|
||||
elements: Vec<Rc<BoundNode<T>>>,
|
||||
},
|
||||
|
||||
Record {
|
||||
layout: std::sync::Arc<crate::ast::types::RecordLayout>,
|
||||
values: Vec<BoundNode<T>>,
|
||||
values: Vec<Rc<BoundNode<T>>>,
|
||||
},
|
||||
|
||||
/// An expanded macro call, preserving the original call for debugging and UI.
|
||||
@@ -164,7 +164,7 @@ pub enum BoundKind<T = ()> {
|
||||
/// The original call from the untyped AST.
|
||||
original_call: Rc<Node<crate::ast::nodes::UntypedKind>>,
|
||||
/// The result of binding the expanded AST.
|
||||
bound_expanded: Box<BoundNode<T>>,
|
||||
bound_expanded: Rc<BoundNode<T>>,
|
||||
},
|
||||
|
||||
/// A diagnostic poison node, allowing compilation to continue after an error.
|
||||
@@ -194,7 +194,7 @@ where
|
||||
addr: ab,
|
||||
value: vb,
|
||||
},
|
||||
) => aa == ab && va == vb,
|
||||
) => aa == ab && Rc::ptr_eq(va, vb),
|
||||
(
|
||||
BoundKind::Define {
|
||||
name: na,
|
||||
@@ -210,12 +210,12 @@ where
|
||||
value: vb,
|
||||
captured_by: cb,
|
||||
},
|
||||
) => na == nb && aa == ab && ka == kb && va == vb && ca == cb,
|
||||
) => na == nb && aa == ab && ka == kb && Rc::ptr_eq(va, vb) && ca == cb,
|
||||
(BoundKind::FieldAccessor(a), BoundKind::FieldAccessor(b)) => a == b,
|
||||
(
|
||||
BoundKind::GetField { rec: ra, field: fa },
|
||||
BoundKind::GetField { rec: rb, field: fb },
|
||||
) => ra == rb && fa == fb,
|
||||
) => Rc::ptr_eq(ra, rb) && fa == fb,
|
||||
(
|
||||
BoundKind::If {
|
||||
cond: ca,
|
||||
@@ -227,7 +227,11 @@ where
|
||||
then_br: tb,
|
||||
else_br: eb,
|
||||
},
|
||||
) => ca == cb && ta == tb && ea == eb,
|
||||
) => Rc::ptr_eq(ca, cb) && Rc::ptr_eq(ta, tb) && match (ea, eb) {
|
||||
(Some(a), Some(b)) => Rc::ptr_eq(a, b),
|
||||
(None, None) => true,
|
||||
_ => false,
|
||||
},
|
||||
(
|
||||
BoundKind::Destructure {
|
||||
pattern: pa,
|
||||
@@ -237,7 +241,7 @@ where
|
||||
pattern: pb,
|
||||
value: vb,
|
||||
},
|
||||
) => pa == pb && va == vb,
|
||||
) => Rc::ptr_eq(pa, pb) && Rc::ptr_eq(va, vb),
|
||||
(
|
||||
BoundKind::Lambda {
|
||||
params: pa,
|
||||
@@ -251,7 +255,7 @@ where
|
||||
body: bb,
|
||||
positional_count: pcb,
|
||||
},
|
||||
) => pa == pb && ua == ub && ba == bb && pca == pcb,
|
||||
) => Rc::ptr_eq(pa, pb) && ua == ub && Rc::ptr_eq(ba, bb) && pca == pcb,
|
||||
(
|
||||
BoundKind::Call {
|
||||
callee: ca,
|
||||
@@ -261,10 +265,14 @@ where
|
||||
callee: cb,
|
||||
args: ab,
|
||||
},
|
||||
) => ca == cb && aa == ab,
|
||||
(BoundKind::Again { args: aa }, BoundKind::Again { args: ab }) => aa == ab,
|
||||
(BoundKind::Block { exprs: ea }, BoundKind::Block { exprs: eb }) => ea == eb,
|
||||
(BoundKind::Tuple { elements: ea }, BoundKind::Tuple { elements: eb }) => ea == eb,
|
||||
) => Rc::ptr_eq(ca, cb) && Rc::ptr_eq(aa, ab),
|
||||
(BoundKind::Again { args: aa }, BoundKind::Again { args: ab }) => Rc::ptr_eq(aa, ab),
|
||||
(BoundKind::Block { exprs: ea }, BoundKind::Block { exprs: eb }) => {
|
||||
ea.len() == eb.len() && ea.iter().zip(eb.iter()).all(|(a, b)| Rc::ptr_eq(a, b))
|
||||
}
|
||||
(BoundKind::Tuple { elements: ea }, BoundKind::Tuple { elements: eb }) => {
|
||||
ea.len() == eb.len() && ea.iter().zip(eb.iter()).all(|(a, b)| Rc::ptr_eq(a, b))
|
||||
}
|
||||
(
|
||||
BoundKind::Record {
|
||||
layout: la,
|
||||
@@ -274,7 +282,7 @@ where
|
||||
layout: lb,
|
||||
values: vb,
|
||||
},
|
||||
) => std::sync::Arc::ptr_eq(la, lb) && va == vb,
|
||||
) => std::sync::Arc::ptr_eq(la, lb) && va.len() == vb.len() && va.iter().zip(vb.iter()).all(|(a, b)| Rc::ptr_eq(a, b)),
|
||||
(
|
||||
BoundKind::Expansion {
|
||||
original_call: ca,
|
||||
@@ -284,9 +292,9 @@ where
|
||||
original_call: cb,
|
||||
bound_expanded: eb,
|
||||
},
|
||||
) => Rc::ptr_eq(ca, cb) && ea == eb,
|
||||
) => Rc::ptr_eq(ca, cb) && Rc::ptr_eq(ea, eb),
|
||||
(BoundKind::Error, BoundKind::Error) => true,
|
||||
(BoundKind::Extension(_), BoundKind::Extension(_)) => false, // Currently no equality for extensions
|
||||
(BoundKind::Extension(_), BoundKind::Extension(_)) => false,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user