From 9df3f193b848d7ec38424c4782c2c2560e183463 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Thu, 7 Nov 2013 00:34:53 -0800 Subject: [PATCH] 3282 - experiment: a new false sym Following 3278, I want to distinguish nil from false inside <. --- 021eval.cc | 6 ++++ 022primitives.cc | 19 +++++++----- 022primitives.test.cc | 17 ++++++++--- 041test.wart | 6 ++++ 042fn.test | 2 +- 045check.test | 54 ++++++++++++++++----------------- 048control.test | 2 +- 050list2.test | 70 +++++++++++++++++++++---------------------- 052num.test | 38 +++++++++++------------ 053string.test | 58 +++++++++++++++++------------------ 054table.test | 6 ++-- 055queue.test | 6 ++-- 057sym.test | 24 +++++++-------- 061patmatch.test | 4 +-- 14 files changed, 169 insertions(+), 143 deletions(-) diff --git a/021eval.cc b/021eval.cc index 4c052552..1b5cdb1a 100644 --- a/021eval.cc +++ b/021eval.cc @@ -57,6 +57,12 @@ cell* eval(cell* expr, cell* scope) { return mkref(expr); } + if (expr == new_sym("false")) { + trace("eval") << "false"; + trace("eval") << "=> " << expr; + return mkref(expr); + } + if (is_sym(expr)) { trace("eval") << "sym"; cell* result = lookup(expr, scope, keep_already_evald()); diff --git a/022primitives.cc b/022primitives.cc index dd32dc62..c1ec1ca1 100644 --- a/022primitives.cc +++ b/022primitives.cc @@ -16,11 +16,11 @@ COMPILE_FN(fn, compiledfn_fn, "'($params ... $body)", ) COMPILE_FN(if, compiledfn_if, "($cond '$then '$else)", - return lookup("$cond") != nil ? eval(lookup("$then")) : eval(lookup("$else")); + return (lookup("$cond") != nil && lookup("$cond") != new_sym("false")) ? eval(lookup("$then")) : eval(lookup("$else")); ) COMPILE_FN(not, compiledfn_not, "($x)", - return lookup("$x") == nil ? mkref(new_num(1)) : nil; + return (lookup("$x") == nil || lookup("$x") == new_sym("false")) ? mkref(new_num(1)) : mkref(new_sym("false")); ) COMPILE_FN(=, compiledfn_equal, "($x $y)", @@ -29,8 +29,12 @@ COMPILE_FN(=, compiledfn_equal, "($x $y)", cell* result = nil; if (x == nil && y == nil) result = new_num(1); + else if (x == new_sym("false") && y == new_sym("false")) + result = new_num(1); else if (x == nil || y == nil) - result = nil; + result = new_sym("false"); + else if (x == new_sym("false") || y == new_sym("false")) + result = new_sym("false"); else if (x == y) result = x; else if (x->type == FLOAT || y->type == FLOAT) @@ -38,7 +42,7 @@ COMPILE_FN(=, compiledfn_equal, "($x $y)", else if (is_string(x) && is_string(y) && to_string(x) == to_string(y)) result = x; else - result = nil; + result = new_sym("false"); return mkref(result); ) @@ -90,8 +94,9 @@ COMPILE_FN(unbind, compiledfn_unbind, "('$var)", COMPILE_FN(bound?, compiledfn_is_bound, "($var $scope)", cell* var = lookup("$var"); if (var == nil) return mkref(new_num(1)); + if (var == new_sym("false")) return mkref(new_num(1)); if (!scope_containing_binding(var, lookup("$scope"))) - return nil; + return mkref(new_sym("false")); return mkref(var); ) @@ -115,7 +120,7 @@ COMPILE_FN(eval, compiledfn_eval, "('$x $scope)", COMPILE_FN(mac?, compiledfn_is_macro, "($f)", cell* f = lookup("$f"); - return is_macro(f) ? mkref(f) : nil; + return is_macro(f) ? mkref(f) : mkref(new_sym("false")); ) COMPILE_FN(uniq, compiledfn_uniq, "($x)", @@ -125,7 +130,7 @@ COMPILE_FN(uniq, compiledfn_uniq, "($x)", //// partial eval COMPILE_FN(warning_on_undefined_var?, compiledfn_is_warning_on_undefined_var, "()", - return Warn_on_unknown_var ? mkref(new_num(1)) : nil; + return Warn_on_unknown_var ? mkref(new_num(1)) : mkref(new_sym("false")); ) COMPILE_FN(stop_warning_on_undefined_var, compiledfn_stop_warning_on_undefined_var, "()", diff --git a/022primitives.test.cc b/022primitives.test.cc index 9ae0d67d..37d7a36e 100644 --- a/022primitives.test.cc +++ b/022primitives.test.cc @@ -41,7 +41,7 @@ void test_if_sees_args_in_then_and_else() { void test_not_works() { run("(not 35)"); - CHECK_TRACE_TOP("eval", "compiled fn=> nil"); + CHECK_TRACE_TOP("eval", "compiled fn=> false"); } void test_not_works2() { @@ -110,7 +110,7 @@ void test_unbind_handles_unbound_vars() { void test_bound_works() { run("(bound? 'a)"); - CHECK_TRACE_TOP("eval", "=> nil"); + CHECK_TRACE_TOP("eval", "=> false"); CLEAR_TRACE; new_dynamic_scope("a", new_num(3)); run("(bound? 'a)"); @@ -121,11 +121,11 @@ void test_bound_works() { void test_bound_checks_only_dynamic_scope_on_nil() { TEMP(call, read("(bound? 'a nil)")); TEMP(result1, eval(call)); - CHECK_EQ(result1, nil); + CHECK_EQ(result1, new_sym("false")); new_lexical_scope(); add_lexical_binding("a", new_num(3)); TEMP(result2, eval(call)); - CHECK_EQ(result2, nil); + CHECK_EQ(result2, new_sym("false")); end_lexical_scope(); } @@ -133,11 +133,20 @@ void test_equal_handles_nil() { trace("test") << "="; run("(nil = nil)"); CHECK_TRACE_DOESNT_CONTAIN("eval", 1, "=> nil"); + CHECK_TRACE_DOESNT_CONTAIN("eval", 1, "=> false"); +} + +void test_equal_handles_false() { + trace("test") << "="; + run("(false = false)"); + CHECK_TRACE_DOESNT_CONTAIN("eval", 1, "=> nil"); + CHECK_TRACE_DOESNT_CONTAIN("eval", 1, "=> false"); } void test_equal_handles_floats() { run("((/ 3.0 2) = 1.5)"); CHECK_TRACE_DOESNT_CONTAIN("eval", 1, "=> nil"); + CHECK_TRACE_DOESNT_CONTAIN("eval", 1, "=> false"); } void test_equal_handles_float_vs_nil() { diff --git a/041test.wart b/041test.wart index 8b61b6c5..ce1e53fb 100644 --- a/041test.wart +++ b/041test.wart @@ -16,3 +16,9 @@ alias equal (=) def (match a b) (match? b a) + +def (be_true x) + x + +def (be_false x) + no.x diff --git a/042fn.test b/042fn.test index ae732864..036eb55c 100644 --- a/042fn.test +++ b/042fn.test @@ -6,7 +6,7 @@ (test "compose works - 2" :valueof ((compose not cons?) '(1 2)) - :should be nil) + :should be_false) (mac! (foo x) `(+ 1 ,x)) (test "compose works with macros" diff --git a/045check.test b/045check.test index ef5a8aa6..f22db9ad 100644 --- a/045check.test +++ b/045check.test @@ -1,6 +1,6 @@ (test "if handles 0 args" :valueof (if) - :should be nil) + :should be_false) (test "if handles 1 arg" :valueof if.3 @@ -43,11 +43,11 @@ (test "or handles 0 args" :valueof (or) - :should be nil) + :should be_false) (test "or handles nil arg" :valueof or.nil - :should be nil) + :should be_false) (test "or handles non-nil arg" :valueof or.3 @@ -65,7 +65,7 @@ :valueof (let x nil (or 3 (x <- 4)) x) - :should be nil) + :should be_false) (test "or evals each arg at most once" :valueof (let x 0 @@ -90,11 +90,11 @@ (test "and handles 0 args" :valueof (and) - :should ~be nil) + :should be_true) (test "and handles nil arg" :valueof and.nil - :should be nil) + :should be_false) (test "and handles non-nil arg" :valueof and.3 @@ -102,7 +102,7 @@ (test "and handles 2 args" :valueof (and nil 3) - :should be nil) + :should be_false) (test "and handles 2 non-nil args" :valueof (and 3 4) @@ -110,7 +110,7 @@ (test "and handles lexical scope" :valueof ((fn(x) (and 3 x 4)) nil) - :should be nil) + :should be_false) (test "and short-circuits" :valueof (let x 0 @@ -133,39 +133,39 @@ (test "equality handles nils" :valueof (nil = 3) - :should be nil) + :should be_false) (test "equality compares nils" :valueof (nil = nil) - :should ~be nil) + :should be_true) (test "equality handles ints" :valueof (3 = 4) - :should be nil) + :should be_false) (test "equality handles ints - 2" :valueof (3 = 3) - :should ~be nil) + :should be_true) (test "equality handles strings" :valueof ("a" = "b") - :should be nil) + :should be_false) (test "equality handles strings - 2" :valueof ("a" = "a") - :should ~be nil) + :should be_true) (test "equality handles lists" :valueof (list.1 = list.2) - :should be nil) + :should be_false) (test "equality handles lists - 2" :valueof (list.1 = list.1) - :should ~be nil) + :should be_true) (test "equality handles user-defined types" :valueof ('(type foo 3) = '(type foo 3)) - :should ~be nil) + :should be_true) @@ -194,43 +194,43 @@ (test "match? - atom positive" :valueof (match? 3 3) - :should ~be nil) + :should be_true) (test "match? - atom negative" :valueof (match? 3 4) - :should be nil) + :should be_false) (test "match? - list positive" :valueof (match? '(1 (2 3)) '(1 (2 3))) - :should ~be nil) + :should be_true) (test "match? - list negative" :valueof (match? '(2 (2 3)) '(1 (2 3))) - :should be nil) + :should be_false) (test "match? treats _ as atom wildcard" :valueof (match? '_ 3) - :should ~be nil) + :should be_true) (test "match? - _ positive" :valueof (match? '(1 (_ 3 4)) '(1 (2 3 4))) - :should ~be nil) + :should be_true) (test "match? - _ negative" :valueof (match? '(2 (_ 3 4)) '(1 (2 3 4))) - :should be nil) + :should be_false) (test "match? - _ matches lists" :valueof (match? '_ '(3)) - :should ~be nil) + :should be_true) (test "match? - _ matches lists when dotted" :valueof (match? '(1 ... _) '(1 2 3)) - :should ~be nil) + :should be_true) (test "match? - _ matches nil when dotted" :valueof (match? '(1 ... _) '(1)) - :should ~be nil) + :should be_true) diff --git a/048control.test b/048control.test index 94687edd..e7976162 100644 --- a/048control.test +++ b/048control.test @@ -20,7 +20,7 @@ (test "aand works" :valueof (let x list.3 (aand x (car.it < 4))) - :should ~be nil) + :should be_true) (test "while works" :valueof (ret ans nil diff --git a/050list2.test b/050list2.test index c460a00e..5d16cc94 100644 --- a/050list2.test +++ b/050list2.test @@ -117,66 +117,66 @@ (test "lists compare lexicographically" :valueof (< '(1 2 3) '(1 2 4)) - :should ~be nil) + :should be_true) (test "lists compare lexicographically - 2" :valueof (< '(1 2 4) '(1 2 3)) - :should be nil) + :should be_false) (test "shorter list compares with prefix" :valueof (< '(1 2 4) '(1 2 3 4)) - :should be nil) + :should be_false) (test "shorter list compares with prefix - 2" :valueof (< '(1 2 2) '(1 2 3 4)) - :should ~be nil) + :should be_true) (test "equal prefixes sort by length" :valueof (< '(1 2 3) '(1 2 3 4)) - :should ~be nil) + :should be_true) (test "equal prefixes sort by length - 2" :valueof (< '(1 2 3 4) '(1 2 3)) - :should be nil) + :should be_false) (test "overloading < also fixes >" :valueof (> '(1 2 4) '(1 2 3)) - :should ~be nil) + :should be_true) (test "overloading < also fixes > - 2" :valueof (> '(1 2 4) nil) - :should ~be nil) + :should be_true) (test "overloading < also fixes > - 3" :valueof (> '(1 2 3) '(1 2 4)) - :should be nil) + :should be_false) (test "overloading < also fixes > - 4" :valueof (> nil '(1 2 4)) - :should be nil) + :should be_false) (test "since nil is less than other lists, ranges don't work for lists - http://arclanguage.org/item?id=18136" :valueof (hiding_warnings (list.1 < list.2 < list.3)) - :should be nil) # broken; don't chain list comparison + :should be_false) # broken; don't chain list comparison (test "pos works" :valueof (pos 2 '(1 2 3)) - :should ~be nil) + :should be_true) (test "pos works - 2" :valueof (pos 4 '(1 2 3)) - :should be nil) + :should be_false) (test "pos works - 3" :valueof (pos nil '(1 2 3)) - :should be nil) + :should be_false) (test "pos works - 4" :valueof (pos nil '(1 nil 2 3)) - :should ~be nil) + :should be_true) (test "rpos works" :valueof (rpos 3 '(0 1 2 3)) @@ -184,51 +184,51 @@ (test "rpos works - 2" :valueof (rpos 3 '(0 1 2)) - :should be nil) + :should be_false) (test "predicate works with a list" :valueof ((predicate '(1 2 3)) 3) - :should ~be nil) + :should be_true) (test "predicate works with a list - 2" :valueof ((predicate '(1 2 3)) 4) - :should be nil) + :should be_false) (test "single? - 1" :valueof (single? nil) - :should be nil) + :should be_false) (test "single? - 2" :valueof (single? '(1)) - :should ~be nil) + :should be_true) (test "single? - 3" :valueof (single? '(1 2)) - :should be nil) + :should be_false) (test "single? - 4" :valueof (single? '(1 ... 2)) - :should be nil) + :should be_false) (test "pair? - 1" :valueof (pair? nil) - :should be nil) + :should be_false) (test "pair? - 2" :valueof (pair? '(1)) - :should be nil) + :should be_false) (test "pair? - 3" :valueof (pair? '(1 2)) - :should ~be nil) + :should be_true) (test "pair? - 4" :valueof (pair? '(1 ... 2)) - :should be nil) + :should be_false) (test "pair? - 5" :valueof (pair? '(1 2 3)) - :should be nil) + :should be_false) @@ -284,35 +284,35 @@ (test "all works with lists" :valueof (all list? '((1) 2)) - :should be nil) + :should be_false) (test "all does not convert to predicate" :valueof (all (list nil 1 nil 1) '(1 3)) - :should ~be nil) + :should be_true) (test "some works" :valueof (some num? '(2 a "b")) - :should ~be nil) + :should be_true) (test "some works - 2" :valueof (some num? '(a "b")) - :should be nil) + :should be_false) (test "some does not convert to predicate" :valueof (some (list nil 1 nil nil) '(1 3)) - :should ~be nil) + :should be_true) (test "some does not convert to predicate - 2" :valueof (some (list nil 1 nil nil) '(1 2 3)) - :should ~be nil) + :should be_true) (test "none works" :valueof (none num? '(2 a "b")) - :should be nil) + :should be_false) (test "none works - 2" :valueof (none num? '(a "b")) - :should ~be nil) + :should be_true) (test "map works with multiary functions" :valueof (map list '(1 2 3) '(2 4 6) '(3 6 9)) diff --git a/052num.test b/052num.test index bdd28d71..6861b731 100644 --- a/052num.test +++ b/052num.test @@ -16,31 +16,31 @@ (test "divides works" :valueof (divides 3 2) - :should be nil) + :should be_false) (test "divides works - 2" :valueof (divides 4 2) - :should ~be nil) + :should be_true) (test "comparing anything to nil always returns nil" :valueof (< 3 nil) - :should be nil) + :should be_false) (test "> works" :valueof (> 3 2 1) - :should ~be nil) + :should be_true) (test "> works - 2" :valueof (> 3 1 2) - :should be nil) + :should be_false) (test "< works" :valueof (< 3 1 2) - :should be nil) + :should be_false) (test "< works - 2" :valueof (< 1 2 3) - :should ~be nil) + :should be_true) (test "< works inside if" :valueof (if (3 < 0) 34 35) @@ -48,35 +48,35 @@ (test "<= works" :valueof (<= 1 2 3) - :should ~be nil) + :should be_true) (test "<= works - 2" :valueof (<= 1 1 3) - :should ~be nil) + :should be_true) (test "<= works - 3" :valueof (<= 1 4 3) - :should be nil) + :should be_false) (test "<= fails on nil" :valueof (<= 1 nil 3) - :should be nil) + :should be_false) (test ">= works" :valueof (>= 3 2 1) - :should ~be nil) + :should be_true) (test ">= works - 2" :valueof (>= 3 1 1) - :should ~be nil) + :should be_true) (test ">= works - 3" :valueof (>= 3 1 2) - :should be nil) + :should be_false) (test ">= fails on nil" :valueof (>= 4 nil 3) - :should be nil) + :should be_false) (test "max works" :valueof (max 0 5 7 9 3 4 21 15) @@ -84,7 +84,7 @@ (test "< works with scorer" :valueof ((< (fn(_) _%3)) 4 2) - :should ~be nil) + :should be_true) (test "sort works" :valueof (sort (<) '(1 12 3)) @@ -96,7 +96,7 @@ (test "floats compare to within a tolerance" :valueof (2 >= 2.0000001) - :should ~be nil) + :should be_true) (test "sum works with zero args" :valueof (sum nil) @@ -112,8 +112,8 @@ (test "range checks work" :valueof (1 <= 1 <= 2) - :should ~be nil) + :should be_true) (test "range checks work - 2" :valueof (3 >= 2 > 2) - :should be nil) + :should be_false) diff --git a/053string.test b/053string.test index d0e88a54..cb6a3a3d 100644 --- a/053string.test +++ b/053string.test @@ -12,7 +12,7 @@ (test "strings can index past final char" :valueof ("abcd" 4) - :should be nil) + :should be_false) (test "strings can take negative indices" :valueof ("abcd" -3) @@ -111,114 +111,114 @@ (test "pos works on strings - 3" :valueof (pos "ba" "abc") - :should be nil) + :should be_false) (test "< works on strings" :valueof ("a" < "b") - :should ~be nil) + :should be_true) (test "< works on strings - 2" :valueof ("b" < "a") - :should be nil) + :should be_false) (test "< works on strings - 3" :valueof ("a" < "a") - :should be nil) + :should be_false) (test "< works on strings - 4" :valueof (< "a" "b" "c") - :should ~be nil) + :should be_true) (test "< works on strings - 5" :valueof (< "a" "b" "a") - :should be nil) + :should be_false) (test "< works on strings - 6" :valueof ("a" < "b" < "c") - :should ~be nil) + :should be_true) (test "< works on strings - 7" :valueof ("a" < "b" < "a") - :should be nil) + :should be_false) (test "> works on strings" :valueof ("a" > "b") - :should be nil) + :should be_false) (test "> works on strings - 2" :valueof ("b" > "a") - :should ~be nil) + :should be_true) (test "> works on strings - 3" :valueof (> "c" "b" "d") - :should be nil) + :should be_false) (test "> works on strings - 4" :valueof (> "c" "b" "a") - :should ~be nil) + :should be_true) (test "> works on strings - 5" :valueof (> "a" "b" "a") - :should be nil) + :should be_false) (test "> works on strings - 6" :valueof ("a" > "a") - :should be nil) + :should be_false) (test "> works on strings - 7" :valueof (> "c" "b" "a") - :should ~be nil) + :should be_true) (test "> works on strings - 8" :valueof (> "c" "b" "c") - :should be nil) + :should be_false) (test "> works on strings - 9" :valueof ("c" > "b" > "a") - :should ~be nil) + :should be_true) (test "> works on strings - 7" :valueof ("c" > "b" > "c") - :should be nil) + :should be_false) (test "<= works on strings" :valueof ("a" <= "b") - :should ~be nil) + :should be_true) (test "<= works on strings - 2" :valueof ("b" <= "a") - :should be nil) + :should be_false) (test "<= works on strings - 3" :valueof ("a" <= "a") - :should ~be nil) + :should be_true) (test "<= works on strings - 4" :valueof (nil <= "a") - :should be nil) + :should be_false) (test "<= works on strings - 5" :valueof ("z" <= nil) - :should be nil) + :should be_false) (test ">= works on strings" :valueof ("a" >= "b") - :should be nil) + :should be_false) (test ">= works on strings - 2" :valueof ("b" >= "a") - :should ~be nil) + :should be_true) (test ">= works on strings - 4" :valueof ("a" >= "a") - :should ~be nil) + :should be_true) (test "range checks work on strings" :valueof ("a" <= "a" <= "b") - :should ~be nil) + :should be_true) (test "range checks work on strings - 2" :valueof ("c" >= "b" > "b") - :should be nil) + :should be_false) diff --git a/054table.test b/054table.test index cfe01ee8..47e32360 100644 --- a/054table.test +++ b/054table.test @@ -27,15 +27,15 @@ (test "equality works on tables" :valueof ((table) = (table)) - :should ~be nil) + :should be_true) (test "equality works on tables - 2" :valueof ((table 'a 1 'b 2) = (table 'b 2 'a 1)) - :should ~be nil) + :should be_true) (test "match? works on table values" :valueof (match? (table 'a '_) (table 'a 'x)) - :should ~be nil) + :should be_true) (test "lists coerce to tables" :valueof (as table '((1 2) (3 4))) diff --git a/055queue.test b/055queue.test index 45b3da0c..725f8fe0 100644 --- a/055queue.test +++ b/055queue.test @@ -15,13 +15,13 @@ (test "empty? works on queues" :valueof (empty? (queue)) - :should ~be nil) + :should be_true) (test "empty? works on queues - 2" :valueof (let q (queue) (enq 1 q) (empty? q)) - :should be nil) + :should be_false) (test "deq works" :valueof (let q (queue '(1 2 3)) @@ -40,4 +40,4 @@ (test "equality works on queues" :valueof ((queue '(1 2 3)) = (queue '(1 2 3))) - :should ~be nil) + :should be_true) diff --git a/057sym.test b/057sym.test index f4b4150b..d71678af 100644 --- a/057sym.test +++ b/057sym.test @@ -4,7 +4,7 @@ (test "sym works on empty string" :valueof (sym "") - :should be nil) + :should be_false) (test "sym works with multiple args" :valueof (string+sym "abc" 42 :def) # keyword retains colon @@ -12,11 +12,11 @@ (test "keyword? works" :valueof (keyword? 'abc) - :should be nil) + :should be_false) (test "keyword? works - 2" :valueof (keyword? :abc) - :should ~be nil) + :should be_true) (test "sym converts keywords" :valueof (sym :abc) @@ -24,41 +24,41 @@ (test "< works with syms" :valueof (< "a" 'b) - :should ~be nil) + :should be_true) (test "match? treats any sym beginning with _ as wildcard" :valueof (match? '(1 ... _x) '(1 2 3)) - :should ~be nil) + :should be_true) (test "match? manages _sym identity" :valueof (match? '(1 _x _x) '(1 2 3)) - :should be nil) + :should be_false) (test "match? manages _sym identity - 2" :valueof (match? '(1 _x _x) '(1 2 2)) - :should ~be nil) + :should be_true) (test "match? matches $vars with their root" :valueof (match? 'a_ 'a3) - :should ~be nil) + :should be_true) (test "match? matches $vars with their root - 2" :valueof (match? 'a_ 'a) - :should be nil) + :should be_false) (test "match? manages $var_sym identity" :valueof (match? '(a_x a_x) '(a3 a3)) - :should ~be nil) + :should be_true) (test "match? manages $var_sym identity - 2" :valueof (match? '(a_x a_x) '(a2 a3)) - :should be nil) + :should be_false) (test "match? manages $var_sym identity - 3" :valueof (match? '(a_x a_x) '(a a3)) - :should be nil) + :should be_false) (test "match integrates with test" :valueof (list 'a3 'a3) diff --git a/061patmatch.test b/061patmatch.test index bf305a83..57420b2c 100644 --- a/061patmatch.test +++ b/061patmatch.test @@ -6,12 +6,12 @@ (test "matching checks for match" :valueof (matching (bar _x) (list 3) x) - :should be nil) + :should be_false) (test "matching checks for match - 2" :valueof (matching (a (_x _y)) (list 'a 3) x) - :should be nil) + :should be_false) (test "matching checks for match - 3" :valueof (matching (a (_x _y)) (list 'a '(3 4))