From 2b310274462c7781ebdc0b102d256f15ba730be0 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Sun, 14 Nov 2021 20:34:58 -0700 Subject: [PATCH] assertLet --- kiss/src/kiss/Macros.hx | 25 ++++++++++++++++--------- kiss/src/test/cases/BasicTestCase.kiss | 5 ++++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/kiss/src/kiss/Macros.hx b/kiss/src/kiss/Macros.hx index 5a887423..3521e286 100644 --- a/kiss/src/kiss/Macros.hx +++ b/kiss/src/kiss/Macros.hx @@ -598,22 +598,27 @@ class Macros { renameAndDeprecate("undefalias", "undefAlias"); // Macros that null-check and extract patterns from enums (inspired by Rust) - function ifLet(wholeExp:ReaderExp, exps:Array, k:KissState) { - wholeExp.checkNumArgs(2, 3, "(ifLet [[enum bindings...]] [thenExp] [?elseExp])"); + function ifLet(assertLet:Bool, wholeExp:ReaderExp, exps:Array, k:KissState) { + var funcName = if (assertLet) "assertLet" else "ifLet"; + var elseExpStr = if (assertLet) "" else " "; + var maxArgs = if (assertLet) 2 else 3; + wholeExp.checkNumArgs(2, maxArgs, '($funcName [] ${elseExpStr})'); var b = wholeExp.expBuilder(); + var bindingList = exps[0].bindingList(funcName); + var firstPattern = bindingList.shift(); + var firstValue = bindingList.shift(); + var firstValueSymbol = b.symbol(); + var thenExp = exps[1]; var elseExp = if (exps.length > 2) { exps[2]; + } else if (assertLet) { + b.callSymbol("throw", [b.str('Assertion binding ${firstValue.def.toString()} -> ${firstPattern.def.toString()} failed')]); } else { b.symbol("null"); }; - var bindingList = exps[0].bindingList("ifLet"); - var firstPattern = bindingList.shift(); - var firstValue = bindingList.shift(); - var firstValueSymbol = b.symbol(); - return b.callSymbol("let", [ b.list([firstValueSymbol, firstValue]), b.callSymbol("if", [ @@ -626,7 +631,7 @@ class Macros { if (bindingList.length == 0) { exps[1]; } else { - ifLet(wholeExp, [ + ifLet(assertLet, wholeExp, [ b.list(bindingList) ].concat(exps.slice(1)), k); } @@ -641,7 +646,7 @@ class Macros { ]); } - macros["ifLet"] = ifLet; + macros["ifLet"] = ifLet.bind(false); macros["whenLet"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { wholeExp.checkNumArgs(2, null, "(whenLet [[enum bindings...]] [body...])"); @@ -663,6 +668,8 @@ class Macros { ]); }; + macros["assertLet"] = ifLet.bind(true); + function awaitLet(wholeExp:ReaderExp, exps:Array, k:KissState) { wholeExp.checkNumArgs(2, null, "(awaitLet [] )"); diff --git a/kiss/src/test/cases/BasicTestCase.kiss b/kiss/src/test/cases/BasicTestCase.kiss index 56e42fcf..2ee4905c 100644 --- a/kiss/src/test/cases/BasicTestCase.kiss +++ b/kiss/src/test/cases/BasicTestCase.kiss @@ -498,7 +498,10 @@ (let [&mut v 1] (unlessLet [2 (begin (+= v 1) v)] (Assert.fail)) - (Assert.equals 2 v)))) + (Assert.equals 2 v)) + + (assertThrows (assertLet [(Some thing) none] thing)) + (Assert.equals 5 (assertLet [(Some thing) some5] thing)))) (function _testRawString [] (Assert.equals #| "\\" |# #"\"#)