Add support for destructuring def
This commit introduces the `DefDestructure` bound kind and modifies the binder, analyzer, type checker, and VM to support destructuring in `def` statements. This allows for pattern matching on the right-hand side of a `def` to bind multiple variables. The parser has been updated to accept patterns in `def` statements. The binder now handles `UntypedKind::Def` with a `target` pattern, rather than a simple `name`. This enables destructuring. The `Gemini.md` documentation has been updated to include a new rule for incremental development.
This commit is contained in:
@@ -186,12 +186,13 @@ impl<E: MacroEvaluator> MacroExpander<E> {
|
||||
})
|
||||
}
|
||||
|
||||
UntypedKind::Def { name, value } => {
|
||||
UntypedKind::Def { target, value } => {
|
||||
let target = self.expand_recursive(*target)?;
|
||||
let value = self.expand_recursive(*value)?;
|
||||
Ok(Node {
|
||||
identity: node.identity,
|
||||
kind: UntypedKind::Def {
|
||||
name,
|
||||
target: Box::new(target),
|
||||
value: Box::new(value),
|
||||
},
|
||||
ty: (),
|
||||
@@ -379,13 +380,13 @@ impl<E: MacroEvaluator> MacroExpander<E> {
|
||||
Ok(self.value_to_node(val, node.identity))
|
||||
}
|
||||
|
||||
UntypedKind::Def { mut name, value } => {
|
||||
name.context = Some(state.expansion_id.clone());
|
||||
UntypedKind::Def { target, value } => {
|
||||
let target = self.expand_template(*target, state)?;
|
||||
let val = self.expand_template(*value, state)?;
|
||||
Ok(Node {
|
||||
identity: node.identity,
|
||||
kind: UntypedKind::Def {
|
||||
name,
|
||||
target: Box::new(target),
|
||||
value: Box::new(val),
|
||||
},
|
||||
ty: (),
|
||||
@@ -613,9 +614,13 @@ mod tests {
|
||||
call,
|
||||
} = &exprs[1].kind
|
||||
{
|
||||
if let UntypedKind::Def { name, .. } = &result.kind {
|
||||
assert_eq!(name.context, Some(call.identity.clone()));
|
||||
assert_eq!(name.name.as_ref(), "y");
|
||||
if let UntypedKind::Def { target, .. } = &result.kind {
|
||||
if let UntypedKind::Parameter(sym) = &target.kind {
|
||||
assert_eq!(sym.context, Some(call.identity.clone()));
|
||||
assert_eq!(sym.name.as_ref(), "y");
|
||||
} else {
|
||||
panic!("Expected Parameter target, got {:?}", target.kind);
|
||||
}
|
||||
} else {
|
||||
panic!("Expected Def result, got {:?}", result.kind);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user