From f4db96ad7156657fda6951d858fcb5be18921bc9 Mon Sep 17 00:00:00 2001 From: Benjamin Valpey Date: Wed, 19 Jun 2024 17:26:22 -0500 Subject: [PATCH 1/3] Add optional support for lambda-style functions --- changelog.md | 3 +- doc/en-us/config.md | 1 + doc/pt-br/config.md | 1 + script/parser/compile.lua | 98 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 99 insertions(+), 4 deletions(-) diff --git a/changelog.md b/changelog.md index 8ddfed5f5..332a23b40 100644 --- a/changelog.md +++ b/changelog.md @@ -1,7 +1,8 @@ # changelog ## Unreleased - +`2024-6-19` +* `NEW` Add support for lambda style functions, `|paramList| expr` is syntactic sugar for `function(paramList) return expr end` ## 3.9.3 `2024-6-11` diff --git a/doc/en-us/config.md b/doc/en-us/config.md index 8dd8c059e..caa3c3a8f 100644 --- a/doc/en-us/config.md +++ b/doc/en-us/config.md @@ -1829,6 +1829,7 @@ Array * ``"!"`` * ``"!="`` * ``"continue"`` +* ``"|lambda|"`` ## default diff --git a/doc/pt-br/config.md b/doc/pt-br/config.md index 7ee6c2ea1..acaed4dc8 100644 --- a/doc/pt-br/config.md +++ b/doc/pt-br/config.md @@ -1829,6 +1829,7 @@ Array * ``"!"`` * ``"!="`` * ``"continue"`` +* ``"|lambda|"`` ## default diff --git a/script/parser/compile.lua b/script/parser/compile.lua index 8dd772dbe..d5a2e162e 100644 --- a/script/parser/compile.lua +++ b/script/parser/compile.lua @@ -2188,13 +2188,14 @@ local function parseActions() end end -local function parseParams(params) +local function parseParams(params, isLambda) local lastSep local hasDots + local endToken = isLambda and '|' or ')' while true do skipSpace() local token = Tokens[Index + 1] - if not token or token == ')' then + if not token or token == endToken then if lastSep then missName() end @@ -2269,7 +2270,7 @@ local function parseParams(params) Index = Index + 2 goto CONTINUE end - skipUnknownSymbol '%,%)%.' + skipUnknownSymbol ('%,%' .. endToken .. '%.') ::CONTINUE:: end return params @@ -2393,6 +2394,91 @@ local function parseFunction(isLocal, isAction) return func end +local function parseLambda(isDoublePipe) + local lambdaLeft = getPosition(Tokens[Index], 'left') + local lambdaRight = getPosition(Tokens[Index], 'right') + local lambda = { + type = 'function', + start = lambdaLeft, + finish = lambdaRight, + bstart = lambdaRight, + keyword = { + [1] = lambdaLeft, + [2] = lambdaRight, + }, + hasReturn = true + } + Index = Index + 2 + local pipeLeft = getPosition(Tokens[Index], 'left') + local pipeRight = getPosition(Tokens[Index], 'right') + skipSpace(true) + local params + local LastLocalCount = LocalCount + -- if nonstandardSymbol for '||' is true it is possible for token to be || when there are no params + if isDoublePipe then + params = { + start = pipeLeft, + finish = pipeRight, + parent = lambda, + type = 'funcargs' + } + else + -- fake chunk to store locals + pushChunk(lambda) + LocalCount = 0 + params = parseParams({}, true) + params.type = 'funcargs' + params.start = pipeLeft + params.finish = lastRightPosition() + params.parent = lambda + lambda.args = params + skipSpace() + if Tokens[Index + 1] == '|' then + pipeRight = getPosition(Tokens[Index], 'right') + lambda.finish = pipeRight + lambda.bstart = pipeRight + if params then + params.finish = pipeRight + end + Index = Index + 2 + skipSpace() + else + lambda.finish = lastRightPosition() + lambda.bstart = lambda.finish + if params then + params.finish = lambda.finish + end + missSymbol '|' + end + end + local child = parseExp() + + + -- don't want popChunk logic here as this is not a real chunk + Chunk[#Chunk] = nil + + if child then + -- create dummy return + local rtn = { + type = 'return', + start = child.start, + finish = child.finish, + parent = lambda, + [1] = child} + child.parent = rtn + lambda[1] = rtn + lambda.returns = {rtn} + lambda.finish = child.finish + lambda.keyword[3] = child.finish + lambda.keyword[4] = child.finish + else + lambda.finish = lastRightPosition() + missExp() + end + LocalCount = LastLocalCount + return lambda +end + local function checkNeedParen(source) local token = Tokens[Index + 1] if token ~= '.' @@ -2485,6 +2571,12 @@ local function parseExpUnit() return parseFunction() end + -- FIXME: Use something other than nonstandardSymbol to check for lambda support + if State.options.nonstandardSymbol['|lambda|'] and (token == '|' + or token == '||') then + return parseLambda(token == '||') + end + local node = parseName() if node then local nameNode = resolveName(node) From 2b37778416c1e858a6d2914eae234a24ce1b8fcb Mon Sep 17 00:00:00 2001 From: Benjamin Valpey <36710691+bavalpey@users.noreply.github.com> Date: Tue, 25 Jun 2024 11:41:10 -0500 Subject: [PATCH 2/3] Undo removal of comment in changelog --- changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.md b/changelog.md index 332a23b40..5bfa71a6c 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,7 @@ # changelog ## Unreleased + `2024-6-19` * `NEW` Add support for lambda style functions, `|paramList| expr` is syntactic sugar for `function(paramList) return expr end` From 4af4e936551ee7d56db0b5e5bb4382a0ba376087 Mon Sep 17 00:00:00 2001 From: Benjamin Valpey <36710691+bavalpey@users.noreply.github.com> Date: Wed, 26 Jun 2024 10:16:50 -0500 Subject: [PATCH 3/3] Remove date in changelog.md --- changelog.md | 1 - 1 file changed, 1 deletion(-) diff --git a/changelog.md b/changelog.md index 13599d569..fa368c718 100644 --- a/changelog.md +++ b/changelog.md @@ -3,7 +3,6 @@ ## Unreleased * `NEW` Add postfix snippet for `unpack` -`2024-6-19` * `NEW` Add support for lambda style functions, `|paramList| expr` is syntactic sugar for `function(paramList) return expr end` ## 3.9.3