From 28af3f8785187f40c5371b261ec36ebf94cf983e Mon Sep 17 00:00:00 2001 From: teo3300 Date: Thu, 21 Dec 2023 19:34:56 +0900 Subject: [PATCH] Fixed type for function apply --- src/env.rs | 18 ++++++++++++------ src/eval.rs | 13 ++++++------- src/types.rs | 2 +- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/env.rs b/src/env.rs index cc695b2..d3c5672 100644 --- a/src/env.rs +++ b/src/env.rs @@ -60,12 +60,15 @@ macro_rules! scream { use crate::printer::prt; use crate::types::MalType as M; -pub fn call_func( - func: &MalType, - args: &[MalType], -) -> Result<(Option, Option<(MalType, Env)>), MalErr> { +pub enum CallFunc { + Builtin(MalType), + MalFun(MalType, Env), +} +pub type CallRet = Result; + +pub fn call_func(func: &MalType, args: &[MalType]) -> CallRet { match func { - M::Fun(func, _) => Ok((Some(func(args)?), None)), + M::Fun(func, _) => Ok(CallFunc::Builtin(func(args)?)), M::MalFun { // eval, params, @@ -77,7 +80,10 @@ pub fn call_func( // It's fine to clone the environment here // since this is when the function is actually called match ast.as_ref() { - M::List(list) => Ok((None, Some((list.last().unwrap_or(&Nil).clone(), inner_env)))), + M::List(list) => Ok(CallFunc::MalFun( + list.last().unwrap_or(&Nil).clone(), + inner_env, + )), _ => scream!(), } } diff --git a/src/eval.rs b/src/eval.rs index 23939ef..6854077 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -1,4 +1,4 @@ -use crate::env::{call_func, car_cdr}; +use crate::env::{call_func, car_cdr, CallFunc, CallRet}; use crate::env::{env_get, env_new, env_set}; use crate::env::{first_last, Env}; use crate::printer::prt; @@ -8,7 +8,7 @@ use std::rc::Rc; /// Resolve the first element of the list as the function name and call it /// with the other elements as arguments -fn eval_func(list: &MalType) -> Result<(Option, Option<(MalType, Env)>), MalErr> { +fn eval_func(list: &MalType) -> CallRet { let list = list.if_list()?; let (func, args) = car_cdr(list)?; call_func(func, args) @@ -138,12 +138,11 @@ pub fn eval(ast: &MalType, env: Env) -> MalRet { let eval_ret = eval_func(apply_list)?; match eval_ret { - (Some(ret), None) => return Ok(ret), - (None, Some(ret)) => { - ast = ret.0; - env = ret.1; + CallFunc::Builtin(ret) => return Ok(ret), + CallFunc::MalFun(fun_ast, fun_env) => { + ast = fun_ast; + env = fun_env; } - _ => panic!("# You should not be here"), } } }; diff --git a/src/types.rs b/src/types.rs index 49ff1d5..b1f9787 100644 --- a/src/types.rs +++ b/src/types.rs @@ -108,7 +108,7 @@ pub fn mal_assert_eq(args: &[MalType]) -> MalRet { let mut message = String::from("Assertion-eq failed: ["); message.push_str( args.iter() - .map(|i| prt(i)) + .map(prt) .collect::>() .join(" ") .as_str(),