diff --git a/kiss/src/kiss/Kiss.hx b/kiss/src/kiss/Kiss.hx index 5339e13b..9f62a9f6 100644 --- a/kiss/src/kiss/Kiss.hx +++ b/kiss/src/kiss/Kiss.hx @@ -362,6 +362,19 @@ class Kiss { public static function forHScript(k:KissState):KissState { var copy = new Cloner().clone(k); copy.hscript = true; + + // Also disallow macros that will error when run in hscript: + function disableMacro(m:String, reason:String) { + copy.macros[m] = (wholeExp:ReaderExp, exps, k) -> { + var b = wholeExp.expBuilder(); + b.callSymbol("throw", [b.str('$m is unavailable in macros because $reason')]); + }; + } + + disableMacro("ifLet", "hscript doesn't support pattern-matching"); + disableMacro("whenLet", "hscript doesn't support pattern-matching"); + disableMacro("unlessLet", "hscript doesn't support pattern-matching"); + return copy; } diff --git a/kiss/src/kiss/Macros.hx b/kiss/src/kiss/Macros.hx index aca931ae..ca3464e5 100644 --- a/kiss/src/kiss/Macros.hx +++ b/kiss/src/kiss/Macros.hx @@ -320,6 +320,26 @@ class Macros { ]); }; + macros["assertThrows"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { + wholeExp.checkNumArgs(1, 2, "(assertThrows [expression] [message])"); + var b = wholeExp.expBuilder(); + var expression = exps[0]; + var basicMessage = '${expression.def.toString()} should have thrown an error'; + var messageExp = if (exps.length > 1) { + b.callSymbol("+", [b.str(basicMessage + ": "), exps[1]]); + } else { + b.str(basicMessage); + }; + + b.callSymbol("try", [ + b.begin([expression, b.callSymbol("throw", [messageExp])]), + b.callSymbol("catch", [b.list([b.typed("Dynamic", b.symbol("error"))]), + b.callSymbol("if", [b.callSymbol("=", [b.symbol("error"), messageExp]), + b.callSymbol("throw", [messageExp]), + b.symbol("true")])]) + ]); + }; + function stringsThatMatch(exp:ReaderExp, formName:String) { return switch (exp.def) { case StrExp(s): diff --git a/kiss/src/test/cases/MacroTestCase.kiss b/kiss/src/test/cases/MacroTestCase.kiss index 9b905195..69e990cd 100644 --- a/kiss/src/test/cases/MacroTestCase.kiss +++ b/kiss/src/test/cases/MacroTestCase.kiss @@ -79,4 +79,14 @@ (function _testSetMacroVar [] (Assert.equals 1 (_testSetMacroVarMacro)) - (Assert.equals 2 (_testSetMacroVarMacro))) \ No newline at end of file + (Assert.equals 2 (_testSetMacroVarMacro))) + +// ifLet and its derivatives should be disabled in defMacro bodies: +(defMacro _testIfLetDisabledMacro [] + (assertThrows (ifLet [a "b"] a)) + (assertThrows (whenLet [a "b"] a)) + (assertThrows (unlessLet [a "b"] a)) + `null) + +(function _testIfLetDisabled [] + (_testIfLetDisabledMacro))