From a5351a88aeced58f782ebe9f8508dbe9d6febba4 Mon Sep 17 00:00:00 2001 From: Alex van de Sandt Date: Sun, 30 Jun 2024 17:37:36 -0400 Subject: [PATCH] Pass function args through child env --- src/callable.rs | 18 ++++++++---------- src/interpreter.rs | 14 ++++++++++---- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/callable.rs b/src/callable.rs index 7810f1d..159f6e2 100644 --- a/src/callable.rs +++ b/src/callable.rs @@ -8,14 +8,16 @@ use crate::{environment::Env, interpreter::RuntimeError, value::Value}; type CallableOutput = Result; pub trait Callable: Debug { - fn arity(&self) -> usize; - fn call(&self, env: &Env, args: &[Value]) -> CallableOutput; + fn params(&self) -> Vec { + Vec::new() + } + fn call(&self, env: &Env) -> CallableOutput; } pub struct NativeFunction { arity: usize, #[allow(clippy::type_complexity)] - implementation: Box CallableOutput>, + implementation: Box CallableOutput>, } impl NativeFunction { @@ -26,7 +28,7 @@ impl NativeFunction { pub fn clock() -> Self { Self { arity: 0, - implementation: Box::new(|_, _| { + implementation: Box::new(|_| { let now = SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) .unwrap() @@ -38,12 +40,8 @@ impl NativeFunction { } impl Callable for NativeFunction { - fn arity(&self) -> usize { - self.arity - } - - fn call(&self, env: &Env, args: &[Value]) -> Result { - (self.implementation)(env, args) + fn call(&self, env: &Env) -> Result { + (self.implementation)(env) } } diff --git a/src/interpreter.rs b/src/interpreter.rs index ce7f251..b71e87d 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -152,7 +152,8 @@ impl Interpreter { }; // Check the arity - if callable.arity() != arguments.len() { + let params = callable.params(); + if params.len() != arguments.len() { return Err(RuntimeError::incorrect_arity( callable.as_ref(), arguments.len(), @@ -166,9 +167,14 @@ impl Interpreter { .map(|arg| Self::interpret_expr(arg, env)) .collect::, _>>()?; + // Define a new env for the call + let calling_env = env.new_child(); + for (param, arg) in params.into_iter().zip(evaluated_args) { + calling_env.define(param, arg) + } + // Call it - //Callable::call(call) - callable.call(env, &evaluated_args) + callable.call(&calling_env) } } } @@ -388,7 +394,7 @@ impl RuntimeError { fn incorrect_arity(callable: &dyn Callable, args_len: usize, callee_span: Span) -> Self { Self::IncorrectArity { - expected: callable.arity(), + expected: callable.params().len(), actual: args_len, span: callee_span.into(), } -- 2.51.2