diff --git a/src/ast/compiler/bound_nodes.rs b/src/ast/compiler/bound_nodes.rs index defa27b..7f8c06c 100644 --- a/src/ast/compiler/bound_nodes.rs +++ b/src/ast/compiler/bound_nodes.rs @@ -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 { - pub addr: Address, + pub addr: Option>, } /// Closure metadata attached to `lambda` nodes. @@ -506,6 +508,11 @@ pub enum NodeKind { Placeholder(Rc>), /// Splice placeholder inside a template (only valid in `SyntaxPhase`). Splice(Rc>), + /// Optimized field access (only created during lowering for `RuntimePhase`). + GetField { + rec: Rc>, + field: crate::ast::types::Keyword, + }, /// Expanded macro call, preserving the original call for debugging. Expansion { original_call: Rc>, @@ -560,6 +567,10 @@ impl Clone for NodeKind

{ 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 PartialEq for NodeKind

{ && 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 NodeKind

{ 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(),