This commit is contained in:
2020-11-24 17:46:28 -07:00
parent 000bd555db
commit de85eee100
5 changed files with 47 additions and 5 deletions

View File

@@ -51,6 +51,8 @@ class Macros {
// TODO when
macros["cond"] = cond;
// Under the hood, (defmacrofun ...) defines a runtime function that accepts Quote arguments and a special form that quotes the arguments to macrofun calls
macros["defmacrofun"] = (exps:Array<ReaderExp>, k:KissState) -> {
if (exps.length < 3)
@@ -107,6 +109,24 @@ class Macros {
return macros;
}
// cond expands telescopically into a nested if expression
static function cond(exps:Array<ReaderExp>, k:KissState) {
return switch (exps[0].def) {
case CallExp(condition, body):
CallExp(Symbol("if").withPos(exps[0].pos), [
condition,
CallExp(Symbol("begin").withPos(exps[0].pos), body).withPos(exps[0].pos),
if (exps.length > 1) {
cond(exps.slice(1), k);
} else {
Symbol("null").withPos(exps[0].pos);
}
]).withPos(exps[0].pos);
default:
throw 'top-level expression of (cond... ) cannot be ${exps[0]}, must be call lists starting with a condition expression';
};
}
static function foldMacro(func:String):MacroFunction {
return (exps:Array<ReaderExp>, k) -> {
CallExp(Symbol("Lambda.fold").withPos(exps[0].pos), [

View File

@@ -62,8 +62,6 @@ class Prelude {
return fullGroups;
}
// TODO put truthy in KissState
// TODO make [] falsy
public static dynamic function truthy(v:Any) {
return switch (Type.typeof(v)) {
case TNull: false;

View File

@@ -163,8 +163,6 @@ class SpecialForms {
EIf(condition, thenExp, elseExp).withContextPos();
};
// TODO cond
return map;
}

View File

@@ -157,4 +157,11 @@ class BasicTestCase extends Test {
function testConstructors() {
Assert.equals("sup", BasicTestCase.myConstructedString);
}
function testCond() {
Assert.equals("this one", BasicTestCase.myCond1);
Assert.equals("the default", BasicTestCase.myCond2);
Assert.equals("this", BasicTestCase.myCond3);
Assert.equals(null, BasicTestCase.myCondFallthrough);
}
}

View File

@@ -103,4 +103,23 @@
(Assert.equals 6 b)
(Assert.equals "stuff" c)))
(defvar myConstructedString (new String "sup"))
(defvar myConstructedString (new String "sup"))
(defvar myCond1 (cond
((= 5 6) "not this")
((= 8 9) "not this either")
((= 1 1) "this one")
(true "not the default")))
(defvar myCond2 (cond
((= 5 6) "not this")
((= 8 9) "not this either")
((= 2 1) "not the third one")
(true "the default")))
(defvar myCond3 (cond
((= 5 5) "this")
(true "default")))
(defvar myCondFallthrough (cond
(false "not this")))