diff options
| author | Marmare314 <49279081+Marmare314@users.noreply.github.com> | 2023-04-26 11:32:11 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-26 11:32:11 +0200 |
| commit | 59957746e91c1322a8ca6d228bcaa0f31941ee1b (patch) | |
| tree | d928dea7c99f1d9f17107aac8008b5b7e870d190 /src/eval/func.rs | |
| parent | 6134e3f4ee5298153c36d344df97f36279931c33 (diff) | |
Pattern as parameter (#854)
Diffstat (limited to 'src/eval/func.rs')
| -rw-r--r-- | src/eval/func.rs | 29 |
1 files changed, 18 insertions, 11 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()) } - _ => {} } } |
