ifLet
This commit is contained in:
@@ -419,7 +419,53 @@ class Macros {
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO macros for ifLet, whenLet (for assign then truthy check), caseLet (for extracting from enums)
|
// Macros that null-check and extract patterns from enums (inspired by Rust)
|
||||||
|
function ifLet(wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) {
|
||||||
|
wholeExp.checkNumArgs(2, null, "(ifLet [[enum bindings...]] [thenExp] [?elseExp])");
|
||||||
|
var b = wholeExp.expBuilder();
|
||||||
|
|
||||||
|
var thenExp = exps[1];
|
||||||
|
var elseExp = if (exps.length > 2) {
|
||||||
|
exps[2];
|
||||||
|
} else {
|
||||||
|
b.symbol("null");
|
||||||
|
};
|
||||||
|
|
||||||
|
var bindingList = exps[0].bindingList("ifLet");
|
||||||
|
var firstPattern = bindingList.shift();
|
||||||
|
var firstValue = bindingList.shift();
|
||||||
|
|
||||||
|
return b.call(
|
||||||
|
b.symbol("if"), [
|
||||||
|
firstValue,
|
||||||
|
b.call(
|
||||||
|
b.symbol("case"), [
|
||||||
|
firstValue,
|
||||||
|
b.call(
|
||||||
|
firstPattern, [
|
||||||
|
if (bindingList.length == 0) {
|
||||||
|
exps[1];
|
||||||
|
} else {
|
||||||
|
ifLet(wholeExp, [
|
||||||
|
b.list(bindingList)
|
||||||
|
].concat(exps.slice(1)), k);
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
b.call(
|
||||||
|
b.symbol("otherwise"), [
|
||||||
|
elseExp
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
elseExp
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
macros["ifLet"] = ifLet;
|
||||||
|
|
||||||
|
// TODO whenLet
|
||||||
|
// wholeExp.checkNumArgs(2, null, "(whenLet [[enum bindings...]] [body...])");
|
||||||
|
// TODO unlessLet
|
||||||
|
// wholeExp.checkNumArgs(2, null, "(unlessLet [[enum bindings...]] [body...])");
|
||||||
|
|
||||||
// TODO use expBuilder()
|
// TODO use expBuilder()
|
||||||
function awaitLet(wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) {
|
function awaitLet(wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) {
|
||||||
|
@@ -269,6 +269,10 @@ class BasicTestCase extends Test {
|
|||||||
function testAssignArith() {
|
function testAssignArith() {
|
||||||
_testAssignArith();
|
_testAssignArith();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testPatternLets() {
|
||||||
|
_testPatternLets();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BasicObject {
|
class BasicObject {
|
||||||
|
@@ -437,3 +437,19 @@
|
|||||||
(Assert.equals 1 num)
|
(Assert.equals 1 num)
|
||||||
(-= num 5 6)
|
(-= num 5 6)
|
||||||
(Assert.equals -10 num))
|
(Assert.equals -10 num))
|
||||||
|
|
||||||
|
(defun _testPatternLets []
|
||||||
|
(let [some5 (Some 5)
|
||||||
|
some6 (Some 6)
|
||||||
|
none None
|
||||||
|
:Null<Option<Any>> oops null]
|
||||||
|
(ifLet [(Some a) some5
|
||||||
|
(Some b) some6]
|
||||||
|
(Assert.equals 11 (+ a b))
|
||||||
|
(Assert.fail))
|
||||||
|
(ifLet [(Some a) oops]
|
||||||
|
(Assert.fail))
|
||||||
|
(ifLet [(Some (or 5 6)) some5]
|
||||||
|
(Assert.pass))
|
||||||
|
(ifLet [(Some a) none]
|
||||||
|
(Assert.fail))))
|
Reference in New Issue
Block a user