From e5d22ae6ad42db3e0cfcd9ea96033e8b5ac2db87 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Sat, 25 Feb 2023 16:22:05 -0700 Subject: [PATCH] Make pattern matching in macros a compiler error. close #173 --- kiss/src/kiss/Helpers.hx | 13 ++++++++++ kiss/src/kiss/SpecialForms.hx | 4 +++ kiss/src/test/cases/BasicTestCase.hx | 4 +++ kiss/src/test/cases/BasicTestCase.kiss | 35 ++++++++++++++++++++++++++ 4 files changed, 56 insertions(+) diff --git a/kiss/src/kiss/Helpers.hx b/kiss/src/kiss/Helpers.hx index 554f83f4..77d7eec9 100644 --- a/kiss/src/kiss/Helpers.hx +++ b/kiss/src/kiss/Helpers.hx @@ -257,6 +257,19 @@ class Helpers { var varsInScope:Array = []; function makeSwitchPattern(patternExp:ReaderExp):Array { return switch (patternExp.def) { + case _ if (k.hscript): + trace(patternExp); + var patternExpr = k.forCaseParsing().convert(patternExp); + [switch (patternExpr.expr) { + case EConst(CString(_, _)): + patternExpr; + case EConst(CInt(_) | CFloat(_)): + patternExpr; + case EConst(CIdent("null")): + patternExpr; + default: + throw KissError.fromExp(caseExp, "case expressions in macros can only match literal values"); + }]; case CallExp({pos: _, def: Symbol("when")}, whenExps): patternExp.checkNumArgs(2, 2, "(when )"); if (guard != null) diff --git a/kiss/src/kiss/SpecialForms.hx b/kiss/src/kiss/SpecialForms.hx index 7c0977ca..cf8138af 100644 --- a/kiss/src/kiss/SpecialForms.hx +++ b/kiss/src/kiss/SpecialForms.hx @@ -371,6 +371,10 @@ class SpecialForms { false; } + if (k.hscript && isTupleCase) { + throw KissError.fromExp(wholeExp, "tuple-matching is not supported in a macro"); + } + var b = wholeExp.expBuilder(); var defaultExpr = switch (cases[-1].def) { case CallExp({pos: _, def: Symbol("otherwise")}, otherwiseExps): diff --git a/kiss/src/test/cases/BasicTestCase.hx b/kiss/src/test/cases/BasicTestCase.hx index 26a7f269..d7e742e6 100644 --- a/kiss/src/test/cases/BasicTestCase.hx +++ b/kiss/src/test/cases/BasicTestCase.hx @@ -435,6 +435,10 @@ class BasicTestCase extends Test { _testLambdaTypeAnnotations(); } + function testCaseMacroError() { + _testCaseMacroError(); + } + var aNullToPrint = null; } diff --git a/kiss/src/test/cases/BasicTestCase.kiss b/kiss/src/test/cases/BasicTestCase.kiss index b5e46f6d..bfa4d889 100644 --- a/kiss/src/test/cases/BasicTestCase.kiss +++ b/kiss/src/test/cases/BasicTestCase.kiss @@ -742,6 +742,41 @@ From:[(assert false (+ \"false \" \"should \" \"have \" \"been \" \"true\"))]" m (Assert.isTrue (lambdaTest 5 6)) (lambdaTest2)) +(defMacro __testCaseMacroError1 [] + (case ["thing" 2] `5)) + +(defMacro __testCaseMacroError2 [] + (case 5 + ((Some v) `false) + (otherwise `false))) + +(defMacro __testCaseMacroError3 [] + (case 5 + ([not this] `false) + (otherwise `false))) + +(defMacro __testCaseMacroError4 [s] + (case (symbolNameValue s) + ("rightSymbol" `true) + (otherwise `false))) + +(defMacro __testCaseMacroError5 [n] + (case (eval n) + (5 `true) + (otherwise `false))) + +(function _testCaseMacroError [] + (assertThrowsAtCompileTime + (__testCaseMacroError1)) + (assertThrowsAtCompileTime + (__testCaseMacroError2)) + (assertThrowsAtCompileTime + (__testCaseMacroError3)) + (Assert.isTrue (__testCaseMacroError4 rightSymbol)) + (Assert.isFalse (__testCaseMacroError4 wrongSymbol)) + (Assert.isTrue (__testCaseMacroError5 5)) + (Assert.isFalse (__testCaseMacroError5 6))) + (function _testHaxeProperties [] (Assert.equals 5 staticProp) (Assert.equals 9 (set staticProp 9))