diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2024-06-27 14:13:55 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-27 14:13:55 +0800 |
commit | b313323384b26953a2da6f17d6f61ce1ba9b1b47 (patch) | |
tree | b0523c2e46b29c88313df2ab8069cac566df0234 | |
parent | ffee37bfb5a2cc34ccd7eec8a819146b53ac4763 (diff) | |
parent | 4af4e936551ee7d56db0b5e5bb4382a0ba376087 (diff) | |
download | lua-language-server-b313323384b26953a2da6f17d6f61ce1ba9b1b47.zip |
Merge pull request #2720 from bavalpey/master
Add support for lambda-style functions
-rw-r--r-- | changelog.md | 1 | ||||
-rw-r--r-- | doc/en-us/config.md | 1 | ||||
-rw-r--r-- | doc/pt-br/config.md | 1 | ||||
-rw-r--r-- | script/parser/compile.lua | 98 |
4 files changed, 98 insertions, 3 deletions
diff --git a/changelog.md b/changelog.md index bd7981be..fa368c71 100644 --- a/changelog.md +++ b/changelog.md @@ -3,6 +3,7 @@ ## Unreleased <!-- Add all new changes here. They will be moved under a version at release --> * `NEW` Add postfix snippet for `unpack` +* `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 8dd8c059..caa3c3a8 100644 --- a/doc/en-us/config.md +++ b/doc/en-us/config.md @@ -1829,6 +1829,7 @@ Array<string> * ``"!"`` * ``"!="`` * ``"continue"`` +* ``"|lambda|"`` ## default diff --git a/doc/pt-br/config.md b/doc/pt-br/config.md index 7ee6c2ea..acaed4dc 100644 --- a/doc/pt-br/config.md +++ b/doc/pt-br/config.md @@ -1829,6 +1829,7 @@ Array<string> * ``"!"`` * ``"!="`` * ``"continue"`` +* ``"|lambda|"`` ## default diff --git a/script/parser/compile.lua b/script/parser/compile.lua index 8dd772db..d5a2e162 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) |