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:
2026-03-21 12:51:39 +01:00
parent 63a474030d
commit 99fef2fc86
+16 -1
View File
@@ -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(),