summaryrefslogtreecommitdiff
path: root/src/eval
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval')
-rw-r--r--src/eval/call.rs2
-rw-r--r--src/eval/mod.rs47
-rw-r--r--src/eval/scope.rs2
3 files changed, 41 insertions, 10 deletions
diff --git a/src/eval/call.rs b/src/eval/call.rs
index 5b0628a8..d57ed144 100644
--- a/src/eval/call.rs
+++ b/src/eval/call.rs
@@ -20,7 +20,7 @@ impl Eval for Spanned<&ExprCall> {
return returned;
} else {
let ty = value.type_name();
- ctx.diag(error!(span, "a value of type {} is not callable", ty));
+ ctx.diag(error!(span, "expected function, found {}", ty));
}
} else if !name.is_empty() {
ctx.diag(error!(span, "unknown function"));
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
+ }
+ }
+}
diff --git a/src/eval/scope.rs b/src/eval/scope.rs
index 62ee7e40..a93de269 100644
--- a/src/eval/scope.rs
+++ b/src/eval/scope.rs
@@ -42,7 +42,7 @@ pub struct Scope {
}
impl Scope {
- // Create a new empty scope.
+ /// Create a new empty scope.
pub fn new() -> Self {
Self::default()
}