summaryrefslogtreecommitdiff
path: root/script
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-06-16 17:24:27 +0800
committer最萌小汐 <sumneko@hotmail.com>2022-06-16 17:24:27 +0800
commitea1c5197c469779ba7cd18f1a8da5da9908f2149 (patch)
tree24e8332c50f247c7d66e4d4cdfe847e2e6b1d9c6 /script
parent2dd1bdb05cb317613cd634208953d8450acf4d52 (diff)
downloadlua-language-server-ea1c5197c469779ba7cd18f1a8da5da9908f2149.zip
fix #1218 don't compile `for` in `local`
would prevent compiling for other keys
Diffstat (limited to 'script')
-rw-r--r--script/parser/guide.lua2
-rw-r--r--script/vm/compiler.lua84
2 files changed, 48 insertions, 38 deletions
diff --git a/script/parser/guide.lua b/script/parser/guide.lua
index 2894f673..28a37dac 100644
--- a/script/parser/guide.lua
+++ b/script/parser/guide.lua
@@ -13,6 +13,8 @@ local type = type
---@field args parser.object[]
---@field locals parser.object[]
---@field returns parser.object[]
+---@field exps parser.object[]
+---@field keys parser.object[]
---@field uri uri
---@field start integer
---@field finish integer
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua
index 5bdb1d3c..29de39ae 100644
--- a/script/vm/compiler.lua
+++ b/script/vm/compiler.lua
@@ -846,6 +846,44 @@ function vm.compileCallArg(arg, call, index)
return vm.getNode(arg)
end
+---@class parser.object
+---@field _iterator? table
+---@field _iterArgs? table
+---@field _iterVars? table<parser.object, vm.node>
+
+---@param source parser.object
+local function compileForVars(source)
+ if source._iterator then
+ return
+ end
+ -- for k, v in pairs(t) do
+ --> for k, v in iterator, status, initValue do
+ --> local k, v = iterator(status, initValue)
+ source._iterator = {
+ type = 'dummyfunc',
+ parent = source,
+ }
+ source._iterArgs = {{},{}}
+ source._iterVars = {}
+ -- iterator
+ selectNode(source._iterator, source.exps, 1)
+ -- status
+ selectNode(source._iterArgs[1], source.exps, 2)
+ -- initValue
+ selectNode(source._iterArgs[2], source.exps, 3)
+ if source.keys then
+ for i, loc in ipairs(source.keys) do
+ local node = getReturn(source._iterator, i, source._iterArgs)
+ if node then
+ if i == 1 then
+ node:removeOptional()
+ end
+ source._iterVars[loc] = node
+ end
+ end
+ end
+end
+
---@param source parser.object
---@return vm.node
local function compileLocal(source)
@@ -917,12 +955,18 @@ local function compileLocal(source)
end
-- for x in ... do
if source.parent.type == 'in' then
- vm.compileNode(source.parent)
+ compileForVars(source.parent)
+ local keyNode = source.parent._iterVars[source]
+ if keyNode then
+ vm.setNode(source, keyNode)
+ end
end
-- for x = ... do
if source.parent.type == 'loop' then
- vm.compileNode(source.parent)
+ if source.parent.loc == source then
+ vm.setNode(source, vm.declareGlobal('type', 'integer'))
+ end
end
vm.getNode(source):setData('hasDefined', hasMarkDoc or hasMarkParam or hasMarkValue)
@@ -1411,42 +1455,6 @@ local compilerSwitch = util.switch()
end
vm.setNode(source, node)
end)
- : case 'in'
- : call(function (source)
- if not source._iterator then
- -- for k, v in pairs(t) do
- --> for k, v in iterator, status, initValue do
- --> local k, v = iterator(status, initValue)
- source._iterator = {
- type = 'dummyfunc',
- parent = source,
- }
- source._iterArgs = {{},{}}
- end
- -- iterator
- selectNode(source._iterator, source.exps, 1)
- -- status
- selectNode(source._iterArgs[1], source.exps, 2)
- -- initValue
- selectNode(source._iterArgs[2], source.exps, 3)
- if source.keys then
- for i, loc in ipairs(source.keys) do
- local node = getReturn(source._iterator, i, source._iterArgs)
- if node then
- if i == 1 then
- node:removeOptional()
- end
- vm.setNode(loc, node)
- end
- end
- end
- end)
- : case 'loop'
- : call(function (source)
- if source.loc then
- vm.setNode(source.loc, vm.declareGlobal('type', 'integer'))
- end
- end)
: case 'doc.type'
: call(function (source)
for _, typeUnit in ipairs(source.types) do