From 410801fa5ba0d8f8fd256243f5ee1e61fc0e6ac2 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Thu, 30 Dec 2021 12:58:58 -0700 Subject: [PATCH] unless guards in case statements --- kiss/src/kiss/Helpers.hx | 10 ++++++++-- kiss/src/test/cases/BasicTestCase.kiss | 4 ++++ projects/kiss-vscode/src/ktxt2/KTxt2Editor.kiss | 3 +-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/kiss/src/kiss/Helpers.hx b/kiss/src/kiss/Helpers.hx index b3e862f7..2d4de08e 100644 --- a/kiss/src/kiss/Helpers.hx +++ b/kiss/src/kiss/Helpers.hx @@ -214,11 +214,17 @@ class Helpers { function makeSwitchPattern(patternExp:ReaderExp):Array { return switch (patternExp.def) { case CallExp({pos: _, def: Symbol("when")}, whenExps): - patternExp.checkNumArgs(2, 2, "(when [guard] [pattern])"); + patternExp.checkNumArgs(2, 2, "(when )"); 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 )"); + 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): diff --git a/kiss/src/test/cases/BasicTestCase.kiss b/kiss/src/test/cases/BasicTestCase.kiss index 3ddcdd67..dc92e53f 100644 --- a/kiss/src/test/cases/BasicTestCase.kiss +++ b/kiss/src/test/cases/BasicTestCase.kiss @@ -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: diff --git a/projects/kiss-vscode/src/ktxt2/KTxt2Editor.kiss b/projects/kiss-vscode/src/ktxt2/KTxt2Editor.kiss index eddab910..e237d0b4 100644 --- a/projects/kiss-vscode/src/ktxt2/KTxt2Editor.kiss +++ b/projects/kiss-vscode/src/ktxt2/KTxt2Editor.kiss @@ -461,8 +461,7 @@ (function nextBlankOutput [] (doFor idx (range (+ 1 elementScrollY) ktxt2Elements.length) (case (nth ktxt2Elements idx) - // TODO add unless guards to case - ((when !(output.trim) (Block (objectWith output))) + ((unless (output.trim) (Block (objectWith output))) (changeElementScrollY ->(set elementScrollY idx)) (scrollToPageTop) (break))