conditional \#when and \#unless

This commit is contained in:
2021-07-12 13:36:40 -06:00
parent 0124c05566
commit 737fd09288
3 changed files with 37 additions and 5 deletions

View File

@@ -176,9 +176,10 @@ class Macros {
macros["#if"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k) -> { macros["#if"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k) -> {
wholeExp.checkNumArgs(2, 3, '(#if [cond] [then] [?else])'); wholeExp.checkNumArgs(2, 3, '(#if [cond] [then] [?else])');
var b = wholeExp.expBuilder();
var conditionExp = exps.shift(); var conditionExp = exps.shift();
var thenExp = exps.shift(); var thenExp = exps.shift();
var elseExp = if (exps.length > 0) exps.shift(); else null; var elseExp = if (exps.length > 0) exps.shift(); else b.symbol("null");
var parser = new Parser(); var parser = new Parser();
var conditionInterp = new KissInterp(true); var conditionInterp = new KissInterp(true);
@@ -198,7 +199,7 @@ class Macros {
} }
}; };
function bodyIf(formName:String, negated:Bool, wholeExp:ReaderExp, args:Array<ReaderExp>, k) { function bodyIf(formName:String, underlyingIf:String, negated:Bool, wholeExp:ReaderExp, args:Array<ReaderExp>, k) {
wholeExp.checkNumArgs(2, null, '($formName [condition] [body...])'); wholeExp.checkNumArgs(2, null, '($formName [condition] [body...])');
var b = wholeExp.expBuilder(); var b = wholeExp.expBuilder();
var condition = if (negated) { var condition = if (negated) {
@@ -209,13 +210,15 @@ class Macros {
} else { } else {
args[0]; args[0];
} }
return b.call(b.symbol("if"), [ return b.call(b.symbol(underlyingIf), [
condition, condition,
b.begin(args.slice(1)) b.begin(args.slice(1))
]); ]);
} }
macros["when"] = bodyIf.bind("when", false); macros["when"] = bodyIf.bind("when", "if", false);
macros["unless"] = bodyIf.bind("unless", true); macros["unless"] = bodyIf.bind("unless", "if", true);
macros["#when"] = bodyIf.bind("#when", "#if", false);
macros["#unless"] = bodyIf.bind("#unless", "#if", true);
macros["cond"] = cond; macros["cond"] = cond;

View File

@@ -17,4 +17,20 @@ class ConditionalCompilationTestCase extends Test {
Assert.isTrue(runningInPyOrJs); Assert.isTrue(runningInPyOrJs);
#end #end
} }
function testWhen() {
#if interp
Assert.equals(6, number());
#else
Assert.equals(5, number());
#end
}
function testUnless() {
#if !interp
Assert.equals(9, number2());
#else
Assert.equals(12, number2());
#end
}
} }

View File

@@ -1,3 +1,16 @@
(defvar runningInHaxe (#if interp true false)) (defvar runningInHaxe (#if interp true false))
(defvar runningInPyOrJs (#if (or py js) true false)) (defvar runningInPyOrJs (#if (or py js) true false))
(defun number []
(let [&mut num 5]
(#when interp
(+= num 5)
(-= num 4))
num))
(defun number2 []
(let [&mut num 12]
(#unless interp
(+= num 5)
(-= num 8))
num))