Fixed type for function apply

This commit is contained in:
teo3300
2023-12-21 19:34:56 +09:00
parent 0b47444836
commit 28af3f8785
3 changed files with 19 additions and 14 deletions

View File

@ -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<MalType>, Option<(MalType, Env)>), MalErr> {
pub enum CallFunc {
Builtin(MalType),
MalFun(MalType, Env),
}
pub type CallRet = Result<CallFunc, MalErr>;
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!(),
}
}

View File

@ -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<MalType>, 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"),
}
}
};

View File

@ -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::<Vec<String>>()
.join(" ")
.as_str(),