diff --git a/kiss/src/kiss/Helpers.hx b/kiss/src/kiss/Helpers.hx index 2d4de08e..1e9c6c4c 100644 --- a/kiss/src/kiss/Helpers.hx +++ b/kiss/src/kiss/Helpers.hx @@ -594,6 +594,7 @@ class Helpers { callField: (fieldName:String, callOn:ReaderExp, args:Array) -> call(field(fieldName, callOn), args), print: (arg:ReaderExp) -> CallExp(Symbol("print").withPosOf(posRef), [arg]).withPosOf(posRef), the: (type:ReaderExp, value:ReaderExp) -> callSymbol("the", [type, value]), + not: (exp:ReaderExp) -> callSymbol("not", [exp]), list: list, str: str, symbol: _symbol, diff --git a/kiss/src/kiss/Macros.hx b/kiss/src/kiss/Macros.hx index 84188a3a..778df75a 100644 --- a/kiss/src/kiss/Macros.hx +++ b/kiss/src/kiss/Macros.hx @@ -1136,6 +1136,13 @@ class Macros { macros["indexOf"] = indexOfMacro.bind(false); macros["lastIndexOf"] = indexOfMacro.bind(true); + // contains is a macro so it can be called on either an Array or a String + macros["contains"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { + wholeExp.checkNumArgs(2, 2, '(contains )'); + var b = wholeExp.expBuilder(); + return b.not(b.callSymbol("=", [b.symbol("-1"), b.callField("indexOf", exps[0], [exps[1]])])); + } + // Under the hood, quoted expressions are just Kiss strings for a KissInterp macros["quote"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { wholeExp.checkNumArgs(1, 1, '(quote )'); diff --git a/kiss/src/test/cases/BasicTestCase.hx b/kiss/src/test/cases/BasicTestCase.hx index 9f278c82..bc58d568 100644 --- a/kiss/src/test/cases/BasicTestCase.hx +++ b/kiss/src/test/cases/BasicTestCase.hx @@ -331,6 +331,10 @@ class BasicTestCase extends Test { function testCaseOnNull() { _testCaseOnNull(); } + + function testContains() { + _testContains(); + } } class BasicObject { diff --git a/kiss/src/test/cases/BasicTestCase.kiss b/kiss/src/test/cases/BasicTestCase.kiss index dc92e53f..ecb8ab68 100644 --- a/kiss/src/test/cases/BasicTestCase.kiss +++ b/kiss/src/test/cases/BasicTestCase.kiss @@ -598,4 +598,11 @@ (function _testCaseOnNull [] (Assert.equals 5 (case null (v 10) (null 5))) (Assert.equals 5 (case null (v 10) (null 5) (otherwise 6))) - (Assert.equals 5 (case null (v 10) (otherwise 5)))) \ No newline at end of file + (Assert.equals 5 (case null (v 10) (otherwise 5)))) + +(function _testContains [] + (assert (contains "abc" "b")) + (assert !(contains "abc" "z")) + (assert (contains [1 2 3] 1)) + (assert !(contains [1 2 3] 5)) + (Assert.pass)) \ No newline at end of file