add not, with a reader macro

This commit is contained in:
2020-11-25 11:43:04 -07:00
parent dab730e3eb
commit 70ff9b7e1b
4 changed files with 19 additions and 1 deletions

View File

@@ -48,6 +48,8 @@ class Reader {
readTable["&"] = (stream) -> MetaExp(nextToken(stream, "a meta symbol like mut, optional, rest")); readTable["&"] = (stream) -> MetaExp(nextToken(stream, "a meta symbol like mut, optional, rest"));
readTable["!"] = (stream:Stream) -> CallExp(Symbol("not").withPos(stream.position()), [assertRead(stream, readTable)]);
// Because macro keys are sorted by length and peekChars(0) returns "", this will be used as the default reader macro: // Because macro keys are sorted by length and peekChars(0) returns "", this will be used as the default reader macro:
readTable[""] = (stream) -> Symbol(nextToken(stream, "a symbol name")); readTable[""] = (stream) -> Symbol(nextToken(stream, "a symbol name"));

View File

@@ -195,6 +195,14 @@ class SpecialForms {
$elseExp; $elseExp;
}; };
map["not"] = (args:Array<ReaderExp>, convert:ExprConversion) -> {
if (args.length != 1)
throw '(not... ) only takes one argument, not $args';
var condition = convert(args[0]);
var truthyExp = macro Prelude.truthy($condition);
macro !$truthyExp;
};
return map; return map;
} }

View File

@@ -173,4 +173,9 @@ class BasicTestCase extends Test {
function testOr() { function testOr() {
Assert.equals(5, BasicTestCase.myOr1); Assert.equals(5, BasicTestCase.myOr1);
} }
function testNot() {
Assert.equals(false, BasicTestCase.myNot1);
Assert.equals(false, BasicTestCase.myNot2);
}
} }

View File

@@ -134,3 +134,6 @@
(deflocal loc &mut "one thing") (deflocal loc &mut "one thing")
(set loc "another thing") (set loc "another thing")
loc) loc)
(defvar myNot1 (not 5))
(defvar myNot2 !5)