summaryrefslogtreecommitdiff
path: root/src/eval/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval/mod.rs')
-rw-r--r--src/eval/mod.rs50
1 files changed, 48 insertions, 2 deletions
diff --git a/src/eval/mod.rs b/src/eval/mod.rs
index 2390a84f..4f0beb34 100644
--- a/src/eval/mod.rs
+++ b/src/eval/mod.rs
@@ -2,12 +2,10 @@
#[macro_use]
mod value;
-mod call;
mod capture;
mod ops;
mod scope;
-pub use call::*;
pub use capture::*;
pub use scope::*;
pub use value::*;
@@ -344,6 +342,54 @@ impl ExprBinary {
}
}
+impl Eval for ExprCall {
+ type Output = Value;
+
+ fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
+ let callee = self.callee.eval(ctx);
+
+ if let Value::Func(func) = callee {
+ let func = func.clone();
+ let mut args = self.args.eval(ctx);
+ let returned = func(ctx, &mut args);
+ args.finish(ctx);
+
+ return returned;
+ } else if callee != Value::Error {
+ ctx.diag(error!(
+ self.callee.span(),
+ "expected function, found {}",
+ callee.type_name(),
+ ));
+ }
+
+ Value::Error
+ }
+}
+
+impl Eval for ExprArgs {
+ type Output = ValueArgs;
+
+ fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
+ let items = self
+ .items
+ .iter()
+ .map(|arg| match arg {
+ ExprArg::Pos(expr) => ValueArg {
+ name: None,
+ value: expr.eval(ctx).with_span(expr.span()),
+ },
+ ExprArg::Named(Named { name, expr }) => ValueArg {
+ name: Some(name.string.clone().with_span(name.span)),
+ value: expr.eval(ctx).with_span(expr.span()),
+ },
+ })
+ .collect();
+
+ ValueArgs { span: self.span, items }
+ }
+}
+
impl Eval for ExprLet {
type Output = Value;