diff options
Diffstat (limited to 'src/eval')
| -rw-r--r-- | src/eval/func.rs | 29 | ||||
| -rw-r--r-- | src/eval/mod.rs | 5 |
2 files changed, 19 insertions, 15 deletions
diff --git a/src/eval/func.rs b/src/eval/func.rs index e3b6a99c..a6e0de84 100644 --- a/src/eval/func.rs +++ b/src/eval/func.rs @@ -276,13 +276,11 @@ pub(super) struct Closure { #[derive(Hash)] pub enum Param { /// A positional parameter: `x`. - Pos(Ident), + Pos(ast::Pattern), /// A named parameter with a default value: `draw: false`. Named(Ident, Value), /// An argument sink: `..args`. Sink(Option<Ident>), - /// A placeholder: `_`. - Placeholder, } impl Closure { @@ -330,9 +328,18 @@ impl Closure { let mut sink_pos_values = None; for p in &closure.params { match p { - Param::Pos(ident) => { - vm.define(ident.clone(), args.expect::<Value>(ident)?); - } + Param::Pos(pattern) => match pattern { + ast::Pattern::Normal(ast::Expr::Ident(ident)) => { + vm.define(ident.clone(), args.expect::<Value>(ident)?) + } + ast::Pattern::Normal(_) => unreachable!(), + _ => { + pattern.define( + &mut vm, + args.expect::<Value>("pattern parameter")?, + )?; + } + }, Param::Sink(ident) => { sink = ident.clone(); if let Some(sink_size) = sink_size { @@ -344,9 +351,6 @@ impl Closure { args.named::<Value>(ident)?.unwrap_or_else(|| default.clone()); vm.define(ident.clone(), value); } - Param::Placeholder => { - args.eat::<Value>()?; - } } } @@ -443,12 +447,15 @@ impl<'a> CapturesVisitor<'a> { for param in expr.params().children() { match param { - ast::Param::Pos(ident) => self.bind(ident), + ast::Param::Pos(pattern) => { + for ident in pattern.idents() { + self.bind(ident); + } + } ast::Param::Named(named) => self.bind(named.name()), ast::Param::Sink(spread) => { self.bind(spread.name().unwrap_or_default()) } - _ => {} } } diff --git a/src/eval/mod.rs b/src/eval/mod.rs index d2ca0e74..e8e1af51 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -1207,14 +1207,11 @@ impl Eval for ast::Closure { let mut params = Vec::new(); for param in self.params().children() { match param { - ast::Param::Pos(name) => { - params.push(Param::Pos(name)); - } + ast::Param::Pos(pattern) => params.push(Param::Pos(pattern)), ast::Param::Named(named) => { params.push(Param::Named(named.name(), named.expr().eval(vm)?)); } ast::Param::Sink(spread) => params.push(Param::Sink(spread.name())), - ast::Param::Placeholder(_) => params.push(Param::Placeholder), } } |
