diff --git a/src/env.rs b/src/env.rs index b47a573..c5a0ae2 100644 --- a/src/env.rs +++ b/src/env.rs @@ -13,8 +13,8 @@ impl Env { } } - pub fn set(&mut self, sym: &str, val: MalType) { - self.data.insert(sym.to_string(), val); + pub fn set(&mut self, sym: &str, val: &MalType) { + self.data.insert(sym.to_string(), val.clone()); } pub fn get(&self, sym: &String) -> MalRet { diff --git a/src/eval.rs b/src/eval.rs index 6a46e83..4f608aa 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -2,14 +2,14 @@ use crate::env::Env; use crate::types::MalType::*; use crate::types::{MalArgs, MalMap, MalRet, MalType}; -fn call_func(func: &MalType, args: MalArgs) -> MalRet { +fn call_func(func: &MalType, args: &[MalType]) -> MalRet { match func { Fun(func) => func(args), _ => Err(format!("{:?} is not a function", func)), } } -fn eval_func(list: MalType) -> MalRet { +fn eval_func(list: &MalType) -> MalRet { match list { List(list) => { let func = &list[0]; @@ -18,7 +18,7 @@ fn eval_func(list: MalType) -> MalRet { } else { &list[0..0] }; - call_func(func, args.to_vec()) + call_func(func, args) } _ => Err("YOU SHOULD NOT BE HERE".to_string()), } @@ -31,17 +31,17 @@ pub fn eval(ast: &MalType, env: &Env) -> MalRet { // Ok(Nil) // Should be the normal behavior Ok(ast.clone()) } else { - eval_func(eval_ast(ast.clone(), env)?) + eval_func(&eval_ast(ast, env)?) } } - _ => eval_ast(ast.clone(), env), + _ => eval_ast(ast, env), } } -fn eval_collection(list: MalArgs, env: &Env) -> Result { +fn eval_collection(list: &MalArgs, env: &Env) -> Result { let mut ret = MalArgs::new(); for el in list { - match eval(&el, env) { + match eval(el, env) { Ok(val) => ret.push(val), Err(err) => return Err(err), } @@ -49,12 +49,12 @@ fn eval_collection(list: MalArgs, env: &Env) -> Result { Ok(ret) } -fn eval_map(map: MalMap, env: &Env) -> MalRet { +fn eval_map(map: &MalMap, env: &Env) -> MalRet { let mut ret = MalMap::new(); for (k, v) in map { - match eval(&v, env) { - Ok(res) => ret.insert(k, res), + match eval(v, env) { + Ok(res) => ret.insert(k.to_string(), res), Err(err) => return Err(err), }; } @@ -62,12 +62,12 @@ fn eval_map(map: MalMap, env: &Env) -> MalRet { Ok(Map(ret)) } -fn eval_ast(ast: MalType, env: &Env) -> MalRet { +fn eval_ast(ast: &MalType, env: &Env) -> MalRet { match ast { - Sym(sym) => env.get(&sym), + Sym(sym) => env.get(sym), List(list) => Ok(List(eval_collection(list, env)?)), Vector(vec) => Ok(Vector(eval_collection(vec, env)?)), Map(map) => eval_map(map, env), - _ => Ok(ast), + _ => Ok(ast.clone()), } } diff --git a/src/types.rs b/src/types.rs index 73ade89..777743a 100644 --- a/src/types.rs +++ b/src/types.rs @@ -7,7 +7,7 @@ pub enum MalType { List(MalArgs), Vector(MalArgs), Map(MalMap), - Fun(fn(MalArgs) -> MalRet), + Fun(fn(&[MalType]) -> MalRet), Sym(String), Key(String), Str(String), @@ -78,7 +78,7 @@ fn if_number(val: &MalType) -> Result { } } -pub fn int_op(set: isize, f: fn(isize, isize) -> isize, args: MalArgs) -> MalRet { +pub fn int_op(set: isize, f: fn(isize, isize) -> isize, args: &[MalType]) -> MalRet { if args.is_empty() { return Ok(Int(set)); } @@ -98,13 +98,13 @@ use crate::env::Env; use MalType::Fun; pub fn env_init(env: &mut Env) { - env.set("quit", Fun(|_| exit(0))); - env.set("+", Fun(|a: MalArgs| int_op(0, |a, b| a + b, a))); - env.set("-", Fun(|a: MalArgs| int_op(0, |a, b| a - b, a))); - env.set("*", Fun(|a: MalArgs| int_op(1, |a, b| a * b, a))); - env.set("/", Fun(|a: MalArgs| int_op(1, |a, b| a / b, a))); + env.set("quit", &Fun(|_| exit(0))); + env.set("+", &Fun(|a: &[MalType]| int_op(0, |a, b| a + b, a))); + env.set("-", &Fun(|a: &[MalType]| int_op(0, |a, b| a - b, a))); + env.set("*", &Fun(|a: &[MalType]| int_op(1, |a, b| a * b, a))); + env.set("/", &Fun(|a: &[MalType]| int_op(1, |a, b| a / b, a))); env.set( "test", - Fun(|_| Ok(Str("This is a test function".to_string()))), + &Fun(|_| Ok(Str("This is a test function".to_string()))), ); }