diff --git a/src/env/core.rs b/src/env/core.rs index d2eaf8e..641521e 100644 --- a/src/env/core.rs +++ b/src/env/core.rs @@ -8,6 +8,33 @@ use crate::node::Node; pub(super) fn core() -> HashMap { [ + // Meta + ( + "eval", + Node::NativeFunc(|env, args| { + arg_count!(1, args.len()); + let ast = args.into_iter().next().unwrap(); + eval_node(env, ast) + }), + ), + ( + "apply", + Node::NativeFunc(|env, args| { + arg_count!(2, args.len()); + + let mut args = args.into_iter(); + let operator = args.next().unwrap(); + let args = match args.next().unwrap() { + Node::List(list) => list, + _ => Err(Error::ExpectedList)?, + }; + + let mut list = vec![operator]; + list.extend(args); + + eval_node(env, Node::List(list)) + }), + ), // Arithmetic operations ( "+", diff --git a/src/evaluator.rs b/src/evaluator.rs index 8e8dd6f..f86a31a 100644 --- a/src/evaluator.rs +++ b/src/evaluator.rs @@ -92,6 +92,9 @@ mod test { #[case(":owo", ":owo")] #[case("()", "()")] #[case("nil", "()")] + // Meta + #[case("(eval (list + 1 1))", "2")] + #[case("(apply + (list 1 2 3))", "6")] // Arithmetic #[case("(+ 1 2)", "3")] #[case("(- 5 1)", "4")]