add (never <pattern>) to case

This commit is contained in:
2022-09-25 20:16:11 +00:00
parent 85f281e2ed
commit 7ac2f802bd
2 changed files with 23 additions and 6 deletions

View File

@@ -322,6 +322,23 @@ class SpecialForms {
// to cover all patterns. // to cover all patterns.
var args:kiss.List<ReaderExp> = args.copy(); var args:kiss.List<ReaderExp> = args.copy();
var cases:kiss.List<ReaderExp> = args.slice(1);
for (i in 0...cases.length) {
switch (cases[i].def) {
case CallExp({pos: _, def: Symbol("never")}, neverExps):
cases[i].checkNumArgs(1, 1, '(never <pattern>)');
var b = cases[i].expBuilder();
var failureError = KissError.fromExp(cases[i], '').toString(AssertionFail);
var colonsInPrefix = if (Sys.systemName() == "Windows") 5 else 4;
cases[i] = b.call(neverExps[0], [
b.callSymbol('throw', [
b.callSymbol('kiss.Prelude.runtimeInsertAssertionMessage', [b.str('${Reader.toString(neverExps[0].def)} should never match pattern ${Reader.toString(neverExps[0].def)}'), b.str(failureError), b.int(colonsInPrefix)])])]);
case CallExp({pos: _, def: Symbol("otherwise")}, _) if (i != cases.length - 1):
throw KissError.fromExp(cases[i], "(otherwise <body...>) branch must come last in a (case <...>) expression");
default:
}
}
var isTupleCase = switch (args[0].def) { var isTupleCase = switch (args[0].def) {
case ListExp(_): case ListExp(_):
true; true;
@@ -330,9 +347,9 @@ class SpecialForms {
} }
var b = wholeExp.expBuilder(); var b = wholeExp.expBuilder();
var defaultExpr = switch (args[-1].def) { var defaultExpr = switch (cases[-1].def) {
case CallExp({pos: _, def: Symbol("otherwise")}, otherwiseExps): case CallExp({pos: _, def: Symbol("otherwise")}, otherwiseExps):
args.pop(); cases.pop();
k.convert(b.begin(otherwiseExps)); k.convert(b.begin(otherwiseExps));
default: default:
null; null;
@@ -342,7 +359,7 @@ class SpecialForms {
var canCompareNull = !isTupleCase; var canCompareNull = !isTupleCase;
var cases = args.slice(1);
// case also override's haxe's switch() behavior by refusing to match null values against <var> patterns. // case also override's haxe's switch() behavior by refusing to match null values against <var> patterns.
if (canCompareNull) { if (canCompareNull) {
var nullExpr = defaultExpr; var nullExpr = defaultExpr;

View File

@@ -363,11 +363,11 @@ From:[(assert false (+ \"false \" \"should \" \"have \" \"been \" \"true\"))]" m
(function _testCase [] (function _testCase []
(case (toOption []) (case (toOption [])
(None (Assert.pass)) (None (Assert.pass))
(otherwise (Assert.fail))) (never otherwise))
(case (toOption "hey") (case (toOption "hey")
(None (Assert.fail)) (never None)
((Some "hey") (Assert.pass)) ((Some "hey") (Assert.pass))
(otherwise (Assert.fail))) (never otherwise))
(Assert.equals 5 (case (toOption 0) (Assert.equals 5 (case (toOption 0)
(otherwise 5))) (otherwise 5)))
// Test case with guards and multiple values // Test case with guards and multiple values