mirror of
https://github.com/teo3300/rust-mal.git
synced 2026-01-12 01:05:32 +01:00
Fixed type for function apply
This commit is contained in:
18
src/env.rs
18
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<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!(),
|
||||
}
|
||||
}
|
||||
|
||||
13
src/eval.rs
13
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<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"),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -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(),
|
||||
|
||||
Reference in New Issue
Block a user