diff --git a/docs/TODO.txt b/docs/TODO.txt index c6b0dd3..2834bd0 100644 --- a/docs/TODO.txt +++ b/docs/TODO.txt @@ -9,8 +9,8 @@ DONE: optional block around a path if it's only one statement DONE: while-then DONE: for-then DONE: break and continue statements +DONE: truthiness rethink -TODO: truthiness rethink TODO: string concat with the + operator TODO: increment & decrement operators TODO: a = b = c = 1; diff --git a/docs/spec.md b/docs/spec.md index 07fcc3c..069f625 100644 --- a/docs/spec.md +++ b/docs/spec.md @@ -123,11 +123,7 @@ Otherwise, constants act just like normal variables. ## Truthyness -Everything is considered "truthy" except: - -* the value `null` -* the value `false` -* the integer and float value `0` +Everything is considered "truthy" except the value `false`. Trying to use `null` in a conditional (except assert) will give an error. ## Print @@ -324,7 +320,7 @@ fn omitFirstInteger(arg1: int, ...rest: [int]) { ## Assert -The `assert` keyword takes 2 parameters, separated by a comma. If the first parameter resolves to be falsy, then the program terminates, and the value of the second parameter is displayed to the user as an error. By default, the error is printed to stderr, but this can be overwritten by the host program. +The `assert` keyword takes 2 parameters, separated by a comma. If the first parameter resolves to be false or is null, then the program terminates, and the value of the second parameter is displayed to the user as an error. By default, the error is printed to stderr, but this can be overwritten by the host program. ``` assert true, "This is fine"; //Good! diff --git a/source/interpreter.c b/source/interpreter.c index 6642e8c..ab9edd9 100644 --- a/source/interpreter.c +++ b/source/interpreter.c @@ -137,7 +137,7 @@ static bool execAssert(Interpreter* interpreter) { return false; } - if (!IS_TRUTHY(lhs)) { + if (IS_NULL(lhs) || !IS_TRUTHY(lhs)) { (*interpreter->assertOutput)(AS_STRING(rhs)); return false; } @@ -396,6 +396,11 @@ static bool execValCast(Interpreter* interpreter) { Literal result = TO_NULL_LITERAL; + if (IS_NULL(value)) { + printf("Can't cast a null value\n"); + return false; + } + //cast the rhs to the type represented by lhs switch(AS_TYPE(type).typeOf) { case LITERAL_BOOLEAN: @@ -599,6 +604,11 @@ static bool execFalseJump(Interpreter* interpreter) { return false; } + if (IS_NULL(lit)) { + printf("Null detected in comparison\n"); + return false; + } + if (!IS_TRUTHY(lit)) { interpreter->count = target + interpreter->codeStart; } diff --git a/source/literal.c b/source/literal.c index 854ba68..a185e64 100644 --- a/source/literal.c +++ b/source/literal.c @@ -323,6 +323,7 @@ void freeLiteral(Literal literal) { bool _isTruthy(Literal x) { if (IS_NULL(x)) { + fprintf(stderr, "Null is neither true nor false"); return false; } @@ -330,16 +331,6 @@ bool _isTruthy(Literal x) { return AS_BOOLEAN(x); } - if (IS_INTEGER(x)) { - return AS_INTEGER(x) != 0; - } - - if (IS_FLOAT(x)) { - return AS_FLOAT(x) != 0; - } - - //TODO: empty string as falsy? - return true; }