basic (case...)
This commit is contained in:
@@ -215,6 +215,39 @@ class SpecialForms {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// TODO (case... ) for switch
|
// TODO (case... ) for switch
|
||||||
|
map["case"] = (wholeExp:ReaderExp, args:kiss.List<ReaderExp>, k:KissState) -> {
|
||||||
|
// Most Lisps don't enforce covering all possible patterns with (case...), but Kiss does,
|
||||||
|
// because pattern coverage is a useful feature of Haxe that Kiss can easily bring along.
|
||||||
|
// To be more similar to other Lisps, Kiss *could* generate a default case that returns null
|
||||||
|
// if no "otherwise" clause is given.
|
||||||
|
|
||||||
|
// Therefore only one case is required in a case statement, because one case could be enough
|
||||||
|
// to cover all patterns.
|
||||||
|
wholeExp.checkNumArgs(2, null, '(case [expression] [cases...] [optional: (otherwise [default])])');
|
||||||
|
var defaultExpr = switch (args[-1].def) {
|
||||||
|
case CallExp({pos: _, def: Symbol("otherwise")}, [otherwiseExp]):
|
||||||
|
args.pop();
|
||||||
|
k.convert(otherwiseExp);
|
||||||
|
default:
|
||||||
|
null;
|
||||||
|
};
|
||||||
|
ESwitch(k.convert(args[0]), [
|
||||||
|
for (caseExp in args.slice(1))
|
||||||
|
switch (caseExp.def) {
|
||||||
|
// TODO support | to generate more than one case value
|
||||||
|
// TODO support guards
|
||||||
|
case CallExp(patternExp, caseBodyExps):
|
||||||
|
{
|
||||||
|
values: [k.convert(patternExp)],
|
||||||
|
expr: k.convert(CallExp(Symbol("begin").withPosOf(caseExp), caseBodyExps).withPosOf(caseExp))
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
throw CompileError.fromExp(caseExp, "case expressions for (case...) must take the form ([pattern] [body...])");
|
||||||
|
}
|
||||||
|
], defaultExpr).withMacroPosOf(wholeExp);
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO macros for ifLet, expectLet, which extract from enums
|
||||||
|
|
||||||
// Type check syntax:
|
// Type check syntax:
|
||||||
map["the"] = (wholeExp:ReaderExp, args:Array<ReaderExp>, k:KissState) -> {
|
map["the"] = (wholeExp:ReaderExp, args:Array<ReaderExp>, k:KissState) -> {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import utest.Test;
|
|||||||
import utest.Assert;
|
import utest.Assert;
|
||||||
import kiss.Prelude;
|
import kiss.Prelude;
|
||||||
import kiss.List;
|
import kiss.List;
|
||||||
|
import haxe.ds.Option;
|
||||||
|
|
||||||
using StringTools;
|
using StringTools;
|
||||||
|
|
||||||
@@ -237,6 +238,10 @@ class BasicTestCase extends Test {
|
|||||||
function testAnonymousObject() {
|
function testAnonymousObject() {
|
||||||
_testAnonymousObject();
|
_testAnonymousObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testCase() {
|
||||||
|
_testCase();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BasicObject {
|
class BasicObject {
|
||||||
|
|||||||
@@ -326,3 +326,17 @@
|
|||||||
b 5)]
|
b 5)]
|
||||||
(Assert.equals "string A" obj.a)
|
(Assert.equals "string A" obj.a)
|
||||||
(Assert.equals 5 obj.b)))
|
(Assert.equals 5 obj.b)))
|
||||||
|
|
||||||
|
(defun toOption [:Dynamic value]
|
||||||
|
(if value (Some value) None))
|
||||||
|
|
||||||
|
(defun _testCase []
|
||||||
|
(case (toOption [])
|
||||||
|
(None (Assert.pass))
|
||||||
|
((Some value) (Assert.fail)))
|
||||||
|
(case (toOption "hey")
|
||||||
|
(None (Assert.fail))
|
||||||
|
((Some "hey") (Assert.pass))
|
||||||
|
(otherwise (Assert.fail)))
|
||||||
|
(Assert.equals 5 (case (toOption 0)
|
||||||
|
(otherwise 5))))
|
||||||
Reference in New Issue
Block a user