summaryrefslogtreecommitdiff
path: root/script/parser
diff options
context:
space:
mode:
authorBenjamin Valpey <bavalpey@users.noreply.github.com>2024-06-19 17:26:22 -0500
committerBenjamin Valpey <bavalpey@users.noreply.github.com>2024-06-19 17:26:22 -0500
commitf4db96ad7156657fda6951d858fcb5be18921bc9 (patch)
tree53970493d15cbf774b6b0cad804edd353ae8049d /script/parser
parent85cb44556575f81a31267fe3c443822f3e97699e (diff)
downloadlua-language-server-f4db96ad7156657fda6951d858fcb5be18921bc9.zip
Add optional support for lambda-style functions
Diffstat (limited to 'script/parser')
-rw-r--r--script/parser/compile.lua98
1 files changed, 95 insertions, 3 deletions
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)