diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-01-30 16:19:57 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-01-30 16:19:57 +0100 |
| commit | 5943f552e512f940d4b76055d51215c23420f03a (patch) | |
| tree | 0e80936f8bda91fb03076b6548bbdace707f74f5 /src/eval/mod.rs | |
| parent | 67047047e82c564d7701c3505c85db6e34223763 (diff) | |
Capture variable by slot instead of value 🎣
Diffstat (limited to 'src/eval/mod.rs')
| -rw-r--r-- | src/eval/mod.rs | 37 |
1 files changed, 18 insertions, 19 deletions
diff --git a/src/eval/mod.rs b/src/eval/mod.rs index af3303af..996c908c 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -160,7 +160,7 @@ impl Eval for Spanned<&Expr> { match self.v { Expr::None => Value::None, Expr::Ident(v) => match ctx.scopes.get(v) { - Some(value) => value.clone(), + Some(slot) => slot.borrow().clone(), None => { ctx.diag(error!(self.span, "unknown variable")); Value::Error @@ -185,7 +185,7 @@ impl Eval for Spanned<&Expr> { Expr::Let(v) => v.with_span(self.span).eval(ctx), Expr::If(v) => v.with_span(self.span).eval(ctx), Expr::For(v) => v.with_span(self.span).eval(ctx), - Expr::CapturedValue(v) => v.clone(), + Expr::Captured(v) => v.borrow().clone(), } } } @@ -341,30 +341,29 @@ impl Spanned<&ExprBinary> { let rhs = self.v.rhs.eval(ctx); let span = self.v.lhs.span; - match &self.v.lhs.v { - Expr::Ident(id) => { - if let Some(slot) = ctx.scopes.get_mut(id) { - *slot = op(std::mem::take(slot), rhs); - return Value::None; - } else if ctx.scopes.is_const(id) { - ctx.diag(error!(span, "cannot assign to a constant")); - } else { + let slot = match &self.v.lhs.v { + Expr::Ident(id) => match ctx.scopes.get(id) { + Some(slot) => slot, + None => { ctx.diag(error!(span, "unknown variable")); + return Value::Error; } - } + }, - Expr::CapturedValue(_) => { - ctx.diag(error!( - span, - "cannot assign to captured expression in a template", - )); - } + Expr::Captured(slot) => slot, _ => { ctx.diag(error!(span, "cannot assign to this expression")); + return Value::Error; } + }; + + if let Ok(mut slot) = slot.try_borrow_mut() { + *slot = op(std::mem::take(&mut slot), rhs); + return Value::None; } + ctx.diag(error!(span, "cannot assign to a constant")); Value::Error } } @@ -377,7 +376,7 @@ impl Eval for Spanned<&ExprLet> { Some(expr) => expr.eval(ctx), None => Value::None, }; - ctx.scopes.define(self.v.pat.v.as_str(), value); + ctx.scopes.def_mut(self.v.pat.v.as_str(), value); Value::None } } @@ -418,7 +417,7 @@ impl Eval for Spanned<&ExprFor> { (for ($($binding:ident => $value:ident),*) in $iter:expr) => { #[allow(unused_parens)] for ($($value),*) in $iter { - $(ctx.scopes.define($binding.as_str(), $value);)* + $(ctx.scopes.def_mut($binding.as_str(), $value);)* if let Value::Template(new) = self.v.body.eval(ctx) { output.extend(new); |
