summaryrefslogtreecommitdiff
path: root/src/eval/mod.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-01-20 21:33:13 +0100
committerLaurenz <laurmaedje@gmail.com>2021-01-20 21:33:13 +0100
commit84ba547c7c80e45cc8edafcde8714973bb2a3a2f (patch)
treee5b7eb97799def1907f9138cbe1fa001060c0196 /src/eval/mod.rs
parentdd246e5bc944f90be7ba2981c2b73520a4bfbf45 (diff)
If expressions 🔀
Diffstat (limited to 'src/eval/mod.rs')
-rw-r--r--src/eval/mod.rs47
1 files changed, 39 insertions, 8 deletions
diff --git a/src/eval/mod.rs b/src/eval/mod.rs
index c7b87aef..50043698 100644
--- a/src/eval/mod.rs
+++ b/src/eval/mod.rs
@@ -180,14 +180,8 @@ impl Eval for Spanned<&Expr> {
Expr::Binary(v) => v.with_span(self.span).eval(ctx),
Expr::Group(v) => v.as_ref().eval(ctx),
Expr::Block(v) => v.as_ref().eval(ctx),
- Expr::Let(v) => {
- let value = match &v.expr {
- Some(expr) => expr.as_ref().eval(ctx),
- None => Value::None,
- };
- ctx.scopes.define(v.pat.v.as_str(), value);
- Value::None
- }
+ Expr::Let(v) => v.with_span(self.span).eval(ctx),
+ Expr::If(v) => v.with_span(self.span).eval(ctx),
}
}
}
@@ -249,3 +243,40 @@ impl Eval for Spanned<&ExprBinary> {
}
}
}
+
+impl Eval for Spanned<&ExprLet> {
+ type Output = Value;
+
+ fn eval(self, ctx: &mut EvalContext) -> Self::Output {
+ let value = match &self.v.expr {
+ Some(expr) => expr.as_ref().eval(ctx),
+ None => Value::None,
+ };
+ ctx.scopes.define(self.v.pat.v.as_str(), value);
+ Value::None
+ }
+}
+
+impl Eval for Spanned<&ExprIf> {
+ type Output = Value;
+
+ fn eval(self, ctx: &mut EvalContext) -> Self::Output {
+ let condition = self.v.condition.eval(ctx);
+ if let Value::Bool(boolean) = condition {
+ if boolean {
+ self.v.if_body.eval(ctx)
+ } else if let Some(expr) = &self.v.else_body {
+ expr.eval(ctx)
+ } else {
+ Value::None
+ }
+ } else {
+ ctx.diag(error!(
+ self.v.condition.span,
+ "expected boolean, found {}",
+ condition.type_name()
+ ));
+ Value::Error
+ }
+ }
+}