unless guards in case statements

This commit is contained in:
2021-12-30 12:58:58 -07:00
parent 9a2e9093a1
commit 5c4927f908
2 changed files with 12 additions and 2 deletions

View File

@@ -214,11 +214,17 @@ class Helpers {
function makeSwitchPattern(patternExp:ReaderExp):Array<Expr> {
return switch (patternExp.def) {
case CallExp({pos: _, def: Symbol("when")}, whenExps):
patternExp.checkNumArgs(2, 2, "(when [guard] [pattern])");
patternExp.checkNumArgs(2, 2, "(when <guard> <pattern>)");
if (guard != null)
throw CompileError.fromExp(caseExp, "case pattern can only have one `when` guard");
throw CompileError.fromExp(caseExp, "case pattern can only have one `when` or `unless` guard");
guard = macro Prelude.truthy(${k.convert(whenExps[0])});
makeSwitchPattern(whenExps[1]);
case CallExp({pos: _, def: Symbol("unless")}, whenExps):
patternExp.checkNumArgs(2, 2, "(unless <guard> <pattern>)");
if (guard != null)
throw CompileError.fromExp(caseExp, "case pattern can only have one `when` or `unless` guard");
guard = macro !Prelude.truthy(${k.convert(whenExps[0])});
makeSwitchPattern(whenExps[1]);
case ListEatingExp(exps) if (exps.length == 0):
throw CompileError.fromExp(patternExp, "list-eating pattern should not be empty");
case ListEatingExp(exps):

View File

@@ -369,6 +369,10 @@
((when false (or 5 6)) (Assert.fail))
((when true (or 7 8 9)) (Assert.fail))
(otherwise (Assert.pass)))
(case 5
((unless true (or 5 6)) (Assert.fail))
((unless false (or 7 8 9)) (Assert.fail))
(otherwise (Assert.pass)))
// In Haxe,
// `switch (Some(true)) { case Some(true | false): "a"; default: "b"; }`
// returns "a", so nested use of `or` in case patterns should also be valid: