diff --git a/src/evaluator/env.rs b/src/evaluator/env.rs index 685acb9..b9f63dd 100644 --- a/src/evaluator/env.rs +++ b/src/evaluator/env.rs @@ -1,6 +1,6 @@ use std::{borrow::Borrow, cell::RefCell, collections::HashMap, rc::Rc}; -use super::{eval_ast_node, Error, Expression}; +use super::{eval_ast_node, Error, Expression, FALSE, TRUE}; use crate::parser::Node; pub type RawEnvironment = HashMap>; @@ -127,6 +127,20 @@ pub fn core_environment() -> Rc { Ok(Rc::new(Expression::HashMap(res))) }), ), + ( + "not", + Expression::NativeFunc(|args| { + if args.len() != 1 { + Err(Error::MismatchedArgCount(1, args.len()))? + } + + if FALSE.with(|inner| &args[0] == inner) { + return Ok(TRUE.with(|inner| inner.clone())); + } + + return Ok(FALSE.with(|inner| inner.clone())); + }), + ), // Branching ( "if", diff --git a/src/evaluator/mod.rs b/src/evaluator/mod.rs index 33d146c..a50d96d 100644 --- a/src/evaluator/mod.rs +++ b/src/evaluator/mod.rs @@ -219,6 +219,10 @@ mod test { #[case("((fn* (a) a) 3)", "3")] #[case("((fn* (a) (+ a 2)) 1)", "3")] #[case("((fn* (a b) (+ a b)) 1 2)", "3")] + #[case("(not false)", "true")] + #[case("(not true)", "false")] + #[case("(not nil)", "false")] + #[case("(not 1)", "false")] fn test_evaluator(#[case] input: &str, #[case] expected: &str) { let env = core_environment(); let tokens = lexer::read(input).unwrap();