diff --git a/kiss/src/kiss/Macros.hx b/kiss/src/kiss/Macros.hx index fb183897..7970d86e 100644 --- a/kiss/src/kiss/Macros.hx +++ b/kiss/src/kiss/Macros.hx @@ -840,6 +840,30 @@ class Macros { ]); }; + k.doc("withTempSet", 2, null, "(withTempSet [] )"); + macros["withTempSet"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { + var b = wholeExp.expBuilder(); + var bindingList = exps[0].bindingList("withTempSet"); + var body = exps.slice(1); + var bindingPairs = Prelude.groups(bindingList, 2); + var exps = [for (pair in bindingPairs) pair[0]]; + var values = [for (pair in bindingPairs) pair[1]]; + var oldValueSymbols = [for (i in 0...bindingPairs.length) b.symbol()]; + var letBindings = Lambda.flatten(Prelude.zipThrow(oldValueSymbols, exps)); + var setBindings:Array> = Prelude.zipThrow(exps, values); + var resetBindings:Array> = Prelude.zipThrow(exps, oldValueSymbols); + var result = b.symbol(); + b.let(letBindings, [ + for (pair in setBindings) + b.set(pair[0], pair[1]) + ].concat([ + b.let([result, b.begin(body)], [ + for (pair in resetBindings) + b.set(pair[0], pair[1]) + ].concat([result])) + ])); + }; + k.doc("defnew", 1, null, "(defNew [] [] "); macros["defnew"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { var args = exps.shift(); diff --git a/kiss/src/test/cases/BasicTestCase.hx b/kiss/src/test/cases/BasicTestCase.hx index 019c161a..31bdfff1 100644 --- a/kiss/src/test/cases/BasicTestCase.hx +++ b/kiss/src/test/cases/BasicTestCase.hx @@ -399,6 +399,10 @@ class BasicTestCase extends Test { _testWithFunctions(); } + function testWithTempSet() { + _testWithTempSet(); + } + function testPrintMacrosCheck() { _testPrintMacrosCheck(); } diff --git a/kiss/src/test/cases/BasicTestCase.kiss b/kiss/src/test/cases/BasicTestCase.kiss index 2cc24b4a..09a0d6c0 100644 --- a/kiss/src/test/cases/BasicTestCase.kiss +++ b/kiss/src/test/cases/BasicTestCase.kiss @@ -751,6 +751,23 @@ From:[(assert false (+ \"false \" \"should \" \"have \" \"been \" \"true\"))]" m (localFunction c [val] (+ (a val) (b val))) (Assert.equals 5 (c 1)))) +(function _testWithTempSet [] + (let [&mut v 5 + &mut v2 3] + (assertEquals 5 v) + (assertEquals 3 v2) + (withTempSet [v 6] + (assertEquals 6 v) + (assertEquals 3 v2)) + (assertEquals 5 v) + (assertEquals 3 v2) + (withTempSet [v 7 v2 9] + (assertEquals 7 v) + (assertEquals 9 v2)) + (assertEquals 5 v) + (assertEquals 3 v2)) + (Assert.pass)) + (var anotherNullToPrint null) (function _testPrintMacrosCheck [] (printAllNulls)