use crate::ast::Val; pub fn eval_f(f: &str, args: &[Val]) -> Val { match f { "quote" if args.len() == 1 => args[0].clone(), _ => Val::Atom("error".to_string()), } } pub fn eval(v: &Val) -> Val { match v { v @ Val::Atom(_) => v.clone(), v @ Val::I64(_) => v.clone(), v @ Val::String(_) => v.clone(), v @ Val::List(vs) => { if vs.is_empty() { return v.clone(); } match &vs[0] { Val::Atom(f) => eval_f(&f, &vs[1..]), _ => v.clone(), } } } } #[cfg(test)] mod tests { use super::*; #[test] fn eval_atom() { assert_eq!( eval(&Val::Atom("x".to_string())), Val::Atom("x".to_string()) ); } #[test] fn eval_i64() { assert_eq!(eval(&Val::I64(1)), Val::I64(1)); } #[test] fn eval_string() { assert_eq!( eval(&Val::String("hello".to_string())), Val::String("hello".to_string()) ); } #[test] fn eval_quote() { assert_eq!( eval(&Val::List(vec!( Val::Atom("quote".to_string()), Val::Atom("x".to_string()) ))), Val::Atom("x".to_string()) ); } }