disable ifLet in defMacro bodies

This commit is contained in:
2021-10-28 13:31:17 -04:00
parent ecd0c50cc5
commit 78cb9900d7
3 changed files with 44 additions and 1 deletions

View File

@@ -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;
}

View File

@@ -320,6 +320,26 @@ class Macros {
]);
};
macros["assertThrows"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, 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):

View File

@@ -79,4 +79,14 @@
(function _testSetMacroVar []
(Assert.equals 1 (_testSetMacroVarMacro))
(Assert.equals 2 (_testSetMacroVarMacro)))
(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))