From f5ac02aedb6fd434e9bee715402ac615ced2071a Mon Sep 17 00:00:00 2001 From: Roman Godmaire Date: Fri, 16 Feb 2024 08:27:36 -0500 Subject: [PATCH] fix: nil and () are identical --- src/evaluator/mod.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/evaluator/mod.rs b/src/evaluator/mod.rs index cfbd766..59f9364 100644 --- a/src/evaluator/mod.rs +++ b/src/evaluator/mod.rs @@ -39,7 +39,7 @@ impl std::fmt::Display for Expression { Expression::Boolean(false) => write!(f, "false"), Expression::Keyword(val) => write!(f, ":{}", val), Expression::String(val) => write!(f, "{}", val), - Expression::Nil => write!(f, "nil"), + Expression::Nil => write!(f, "()"), Expression::Vector(vec) => { let s = vec @@ -93,6 +93,12 @@ pub fn eval(env: Rc, ast: Vec) -> Result>> fn eval_ast_node(env: Rc, ast_node: Node) -> Result> { let expr = match ast_node { Node::List(list) => { + // Empty lists are nil in scheme + if list.is_empty() { + return Ok(NIL.with(|v| v.clone())); + } + + // We always assume lists evaluate let mut list = list.into_iter(); let operator = eval_ast_node(env.clone(), list.next().ok_or(Error::InvalidOperator)?)?; @@ -135,10 +141,13 @@ mod test { use rstest::rstest; #[rstest] - // Basic test of raw values + // Raw values #[case("1", "1")] #[case("\"uwu\"", "uwu")] #[case(":owo", ":owo")] + #[case("()", "()")] + #[case("nil", "()")] + // Arithmetic #[case("(+ 1 2)", "3")] #[case("(- 5 1)", "4")] #[case("(* 8 9)", "72")] @@ -161,7 +170,7 @@ mod test { // Environment manipulation #[case("(define! asdf (+ 2 2)) (+ asdf 2)", "4\n6")] #[case("(let* (a 2) (+ a 2))", "4")] - // If-else + // Branching #[case("(if true true false)", "true")] #[case("(if nil true false)", "true")] #[case("(if false true false)", "false")]