Refactor Destructure to handle assignments

Renames `DefDestructure` to `Destructure` to better reflect its use in
both definitions and assignments.
Introduces `bind_assign_pattern` to handle assignment destructuring in
the binder.
Adds `test_assign_destructuring` to verify assignment destructuring
functionality.
This commit is contained in:
Michael Schimmel
2026-02-24 08:51:24 +01:00
parent 2b0e7f49d7
commit 51d83562de
9 changed files with 162 additions and 16 deletions
+37 -2
View File
@@ -209,7 +209,7 @@ impl Binder {
Ok(self.make_node(
node.identity.clone(),
BoundKind::DefDestructure {
BoundKind::Destructure {
pattern: Box::new(target_node),
value: Box::new(val_node),
},
@@ -230,7 +230,14 @@ impl Binder {
},
))
} else {
Err("Assignment target must be an identifier".to_string())
let target_node = self.bind_assign_pattern(target)?;
Ok(self.make_node(
node.identity.clone(),
BoundKind::Destructure {
pattern: Box::new(target_node),
value: Box::new(val_node),
},
))
}
}
@@ -456,6 +463,34 @@ impl Binder {
}
}
fn bind_assign_pattern(&mut self, node: &Node<UntypedKind>) -> Result<BoundNode, String> {
match &node.kind {
UntypedKind::Identifier(sym) => {
let addr = self.resolve_variable(sym)?;
Ok(self.make_node(
node.identity.clone(),
BoundKind::Set {
addr,
value: Box::new(self.make_node(node.identity.clone(), BoundKind::Nop)),
},
))
}
UntypedKind::Tuple { elements } => {
let mut bound_elems = Vec::new();
for e in elements {
bound_elems.push(self.bind_assign_pattern(e)?);
}
Ok(self.make_node(
node.identity.clone(),
BoundKind::Tuple {
elements: bound_elems,
},
))
}
_ => Err(format!("Invalid node in assignment pattern: {:?}", node.kind)),
}
}
fn make_node(&self, identity: Identity, kind: BoundKind<()>) -> BoundNode {
Node {
identity,