diff --git a/src/env/core.rs b/src/env/core.rs index 7272c52..6e6e433 100644 --- a/src/env/core.rs +++ b/src/env/core.rs @@ -129,6 +129,19 @@ pub(super) fn core() -> HashMap { Ok(Node::Boolean(false)) }), ), + ( + "empty?", + Node::NativeFunc(|_env, args| { + arg_count!(1, args.len()); + + match args[0].borrow() { + Node::List(list) => Ok(Node::Boolean(list.is_empty())), + Node::Vector(vec) => Ok(Node::Boolean(vec.is_empty())), + Node::Map(map) => Ok(Node::Boolean(map.is_empty())), + _ => Err(Error::ExpectedCollection)?, + } + }), + ), // Ordering ( "eq?", diff --git a/src/error.rs b/src/error.rs index 0e6ba91..5a3e863 100644 --- a/src/error.rs +++ b/src/error.rs @@ -8,6 +8,8 @@ pub enum Error { InvalidOperator, #[error("expected symbol")] ExpectedSymbol, + #[error("expected list, vector, or map")] + ExpectedCollection, #[error("expected list")] ExpectedList, #[error("expected number")] diff --git a/src/evaluator.rs b/src/evaluator.rs index 15be10f..1deb090 100644 --- a/src/evaluator.rs +++ b/src/evaluator.rs @@ -112,14 +112,20 @@ mod test { #[case("(list 1 2 3)", "(1 2 3)")] #[case("(list? (list))", "true")] #[case("(list? 23)", "false")] + #[case("(empty? (list 1 2 3))", "false")] + #[case("(empty? (list))", "true")] // Vectors #[case("(vector 1 2 3)", "[1 2 3]")] #[case("(vector? [])", "true")] #[case("(vector? 23)", "false")] + #[case("(empty? [1 2 3])", "false")] + #[case("(empty? [])", "true")] // Hashmaps #[case("(hashmap :a 1)", "{:a: 1}")] #[case("(hashmap? {})", "true")] #[case("(hashmap? 23)", "false")] + #[case("(empty? {:a 1})", "false")] + #[case("(empty? {})", "true")] // Environment manipulation #[case("(define! asdf (+ 2 2)) (+ asdf 2)", "4\n6")] #[case("(let* (a 2) (+ a 2))", "4")]