diff --git a/kiss/src/kiss/Reader.hx b/kiss/src/kiss/Reader.hx index aabcb027..b195cc5f 100644 --- a/kiss/src/kiss/Reader.hx +++ b/kiss/src/kiss/Reader.hx @@ -6,6 +6,7 @@ import kiss.Kiss; using kiss.Reader; using kiss.Stream; +using kiss.Helpers; typedef ReaderExp = { pos:Position, @@ -92,7 +93,32 @@ class Reader { readTable[","] = (stream, k) -> Unquote(assertRead(stream, k)); readTable[",@"] = (stream, k) -> UnquoteList(assertRead(stream, k)); - // TODO make {...} a macro for (begin ...) + // Lambda arrow syntaxes: + // ->[args] body + // ->arg body + // ->{body} + readTable["->"] = (stream, k) -> { + var firstExp = assertRead(stream, k); + var b = firstExp.expBuilder(); + + var argsExp:ReaderExp = null; + var bodyExp:ReaderExp = null; + + switch (firstExp.def) { + case ListExp(_): + argsExp = firstExp; + bodyExp = assertRead(stream, k); + case Symbol(_): + argsExp = b.list([firstExp]); + bodyExp = assertRead(stream, k); + case CallExp({pos: _, def: Symbol("begin")}, _): + argsExp = b.list([]); + bodyExp = firstExp; + default: + throw CompileError.fromExp(firstExp, "first expression after -> should be [args...], arg, or {body}"); + } + CallExp(b.symbol("lambda"), [argsExp, bodyExp]); + }; // Because macro keys are sorted by length and peekChars(0) returns "", this will be used as the default reader macro: readTable[""] = (stream, k) -> Symbol(nextToken(stream, "a symbol name")); diff --git a/kiss/src/test/cases/BasicTestCase.hx b/kiss/src/test/cases/BasicTestCase.hx index 518b2221..0bb8d889 100644 --- a/kiss/src/test/cases/BasicTestCase.hx +++ b/kiss/src/test/cases/BasicTestCase.hx @@ -281,6 +281,10 @@ class BasicTestCase extends Test { function testKissStrings() { _testKissStrings(); } + + function testArrowLambdas() { + _testArrowLambdas(); + } } class BasicObject { diff --git a/kiss/src/test/cases/BasicTestCase.kiss b/kiss/src/test/cases/BasicTestCase.kiss index 3845a5dd..a7d3e6f1 100644 --- a/kiss/src/test/cases/BasicTestCase.kiss +++ b/kiss/src/test/cases/BasicTestCase.kiss @@ -466,4 +466,17 @@ num 3 l1 ["a" "b" "c"] l2 [1 2 3]] - (Assert.equals "it's 3asy as [a,b,c] [1,2,3]" "$str ${num}asy as $l1 $l2"))) \ No newline at end of file + (Assert.equals "it's 3asy as [a,b,c] [1,2,3]" "$str ${num}asy as $l1 $l2"))) + +(defun _testArrowLambdas [] + (let [withArgs + ->[arg1 arg2] (+ arg1 arg2) + withArg + ->arg (* 2 arg) + withoutArgs + ->{ + (+ 5) + 6}] + (Assert.equals 11 (withArgs 5 6)) + (Assert.equals 12 (withArg 6)) + (Assert.equals 6 (withoutArgs)))) \ No newline at end of file