Refactor AssignBinding and add GetField node
The `AssignBinding` struct now uses `Option<Address<L>>` to differentiate between simple assignments and destructuring assignments. For destructuring, the addresses are managed by the `Identifier` nodes within the target pattern. A new `GetField` node kind has been introduced to represent optimized field access, which is generated during the lowering phase for the `RuntimePhase`. This change aids in more efficient code generation for accessing fields.
This commit is contained in:
@@ -102,9 +102,11 @@ pub struct DefBinding {
|
||||
}
|
||||
|
||||
/// Target address attached to `assign` nodes.
|
||||
/// `Some(addr)` for simple assignment, `None` for destructuring assignment
|
||||
/// (where addresses live on the individual `Identifier` nodes in the target pattern).
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct AssignBinding<L = VirtualId> {
|
||||
pub addr: Address<L>,
|
||||
pub addr: Option<Address<L>>,
|
||||
}
|
||||
|
||||
/// Closure metadata attached to `lambda` nodes.
|
||||
@@ -506,6 +508,11 @@ pub enum NodeKind<P: CompilerPhase = SyntaxPhase> {
|
||||
Placeholder(Rc<Node<P>>),
|
||||
/// Splice placeholder inside a template (only valid in `SyntaxPhase`).
|
||||
Splice(Rc<Node<P>>),
|
||||
/// Optimized field access (only created during lowering for `RuntimePhase`).
|
||||
GetField {
|
||||
rec: Rc<Node<P>>,
|
||||
field: crate::ast::types::Keyword,
|
||||
},
|
||||
/// Expanded macro call, preserving the original call for debugging.
|
||||
Expansion {
|
||||
original_call: Rc<Node<SyntaxPhase>>,
|
||||
@@ -560,6 +567,10 @@ impl<P: CompilerPhase> Clone for NodeKind<P> {
|
||||
fields: fields.clone(),
|
||||
layout: layout.clone(),
|
||||
},
|
||||
NodeKind::GetField { rec, field } => NodeKind::GetField {
|
||||
rec: rec.clone(),
|
||||
field: *field,
|
||||
},
|
||||
NodeKind::MacroDecl { name, params, body } => NodeKind::MacroDecl {
|
||||
name: name.clone(),
|
||||
params: params.clone(),
|
||||
@@ -623,6 +634,9 @@ impl<P: CompilerPhase> PartialEq for NodeKind<P> {
|
||||
&& fa.len() == fb.len()
|
||||
&& fa.iter().zip(fb.iter()).all(|((ka, va), (kb, vb))| Rc::ptr_eq(ka, kb) && Rc::ptr_eq(va, vb))
|
||||
}
|
||||
(NodeKind::GetField { rec: ra, field: fa }, NodeKind::GetField { rec: rb, field: fb }) => {
|
||||
Rc::ptr_eq(ra, rb) && fa == fb
|
||||
}
|
||||
(NodeKind::MacroDecl { name: na, params: pa, body: ba }, NodeKind::MacroDecl { name: nb, params: pb, body: bb }) => {
|
||||
na == nb && Rc::ptr_eq(pa, pb) && Rc::ptr_eq(ba, bb)
|
||||
}
|
||||
@@ -655,6 +669,7 @@ impl<P: CompilerPhase> NodeKind<P> {
|
||||
NodeKind::Block { .. } => "BLOCK".to_string(),
|
||||
NodeKind::Tuple { elements } => format!("TUPLE({})", elements.len()),
|
||||
NodeKind::Record { fields, .. } => format!("RECORD({})", fields.len()),
|
||||
NodeKind::GetField { field, .. } => format!("GET_FIELD(.{})", field.name()),
|
||||
NodeKind::MacroDecl { name, .. } => format!("MACRO({})", name.name),
|
||||
NodeKind::Template(_) => "TEMPLATE".to_string(),
|
||||
NodeKind::Placeholder(_) => "PLACEHOLDER".to_string(),
|
||||
|
||||
Reference in New Issue
Block a user