diff --git a/src/evaluator/mod.rs b/src/evaluator/mod.rs index 5223c3c..fd28c6c 100644 --- a/src/evaluator/mod.rs +++ b/src/evaluator/mod.rs @@ -126,7 +126,7 @@ fn apply_function(fn_obj: Object, args: Vec) -> anyhow::Result { let mut extend_env = extend_function_env(fn_value.clone(), args); trace!("[apply_function] extend_env is {:?}", extend_env); - let evaluated = eval(fn_value.body.into(), &mut extend_env)?; + let evaluated = eval(fn_value.body().clone().into(), &mut extend_env)?; trace!("[apply_function] call function result is {}", evaluated); Ok(evaluated) @@ -149,7 +149,7 @@ fn eval_hash_literal(node: HashLiteral, env: &mut Environment) -> anyhow::Result } fn extend_function_env(fn_obj: Function, args: Vec) -> Environment { - let mut env = Environment::new_enclosed_environment(fn_obj.env.clone()); + let mut env = Environment::new_enclosed_environment(fn_obj.env().clone()); for (param_idx, param) in fn_obj.parameters().iter().enumerate() { env.store(param.value.clone(), args[param_idx].clone()); // TODO need imporve } diff --git a/src/evaluator/tests.rs b/src/evaluator/tests.rs index 3ec7904..272d3f9 100644 --- a/src/evaluator/tests.rs +++ b/src/evaluator/tests.rs @@ -540,8 +540,8 @@ fn test_function_object() -> anyhow::Result<()> { let expected_body = "(x + 2);"; - if format!("{}", value.body) != expected_body { - eprintln!("body is not {}. got = {}", expected_body, value.body); + if format!("{}", value.body()) != expected_body { + eprintln!("body is not {}. got = {}", expected_body, value.body()); } Ok(()) diff --git a/src/object/built_in_function.rs b/src/object/built_in_function.rs index 72818fd..3f14099 100644 --- a/src/object/built_in_function.rs +++ b/src/object/built_in_function.rs @@ -10,26 +10,29 @@ use std::fmt::{Display, Formatter}; const BUILD_FUNC: &str = "builtin function"; +type BuildBoxFuncType = Box) -> anyhow::Result>; +type BuildFuncType = fn(Vec) -> anyhow::Result; + #[derive(Debug, Clone, PartialOrd, PartialEq, Eq, Ord, Hash)] pub struct Builtin { - built_in_function: Box) -> anyhow::Result>, + built_in_function: BuildBoxFuncType, } impl Builtin { - pub fn new(func: fn(Vec) -> anyhow::Result) -> Self { + pub fn new(func: BuildFuncType) -> Self { Self { built_in_function: Box::new(func), } } - pub fn value(&self) -> &Box) -> anyhow::Result> { + pub fn value(&self) -> &BuildBoxFuncType { &self.built_in_function } } impl Display for Builtin { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "built_in_function") + write!(f, "{}", BUILD_FUNC) } } diff --git a/src/object/function.rs b/src/object/function.rs index 7adcd10..d9b25fc 100644 --- a/src/object/function.rs +++ b/src/object/function.rs @@ -10,8 +10,8 @@ use string_join::Join; #[derive(Debug, Clone, PartialOrd, PartialEq, Eq, Ord, Hash)] pub struct Function { parameters: Vec, - pub body: BlockStatement, - pub env: Environment, + body: BlockStatement, + env: Environment, } impl Function { @@ -25,6 +25,14 @@ impl Function { pub fn parameters(&self) -> &Vec { &self.parameters } + + pub fn body(&self) -> &BlockStatement { + &self.body + } + + pub fn env(&self) -> &Environment { + &self.env + } } impl Display for Function {