Skip to content
This repository has been archived by the owner on Jan 16, 2021. It is now read-only.

Commit

Permalink
3282 - experiment: a new false sym
Browse files Browse the repository at this point in the history
Following 3278, I want to distinguish nil from false inside <.
  • Loading branch information
akkartik committed Nov 7, 2013
1 parent 1375bcc commit 9df3f19
Show file tree
Hide file tree
Showing 14 changed files with 169 additions and 143 deletions.
6 changes: 6 additions & 0 deletions 021eval.cc
Expand Up @@ -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());
Expand Down
19 changes: 12 additions & 7 deletions 022primitives.cc
Expand Up @@ -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)",
Expand All @@ -29,16 +29,20 @@ 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)
result = (equal_floats(to_float(x), to_float(y)) ? x : nil);
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);
)

Expand Down Expand Up @@ -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);
)

Expand All @@ -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)",
Expand All @@ -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, "()",
Expand Down
17 changes: 13 additions & 4 deletions 022primitives.test.cc
Expand Up @@ -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() {
Expand Down Expand Up @@ -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)");
Expand All @@ -121,23 +121,32 @@ 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();
}

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() {
Expand Down
6 changes: 6 additions & 0 deletions 041test.wart
Expand Up @@ -16,3 +16,9 @@ alias equal (=)

def (match a b)
(match? b a)

def (be_true x)
x

def (be_false x)
no.x
2 changes: 1 addition & 1 deletion 042fn.test
Expand Up @@ -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"
Expand Down
54 changes: 27 additions & 27 deletions 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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -90,27 +90,27 @@

(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
:should be 3)

(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)
:should be 4)

(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
Expand All @@ -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)



Expand Down Expand Up @@ -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)



Expand Down
2 changes: 1 addition & 1 deletion 048control.test
Expand Up @@ -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
Expand Down

0 comments on commit 9df3f19

Please sign in to comment.