summaryrefslogtreecommitdiff
path: root/script/vm
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-04-19 02:31:50 +0800
committer最萌小汐 <sumneko@hotmail.com>2022-04-19 02:31:50 +0800
commitfa191ea61477047c4754b730f129f96239ddb93e (patch)
tree84c9f60d23c82960b72f3a526bdd3aeeaadf46b1 /script/vm
parent9b91ebedd8ede80fcd0c001fffe96d2a10e41b39 (diff)
downloadlua-language-server-fa191ea61477047c4754b730f129f96239ddb93e.zip
cleanup
Diffstat (limited to 'script/vm')
-rw-r--r--script/vm/compiler.lua54
-rw-r--r--script/vm/init.lua1
-rw-r--r--script/vm/local-compiler.lua68
3 files changed, 83 insertions, 40 deletions
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua
index 4b81f2c7..ba1559be 100644
--- a/script/vm/compiler.lua
+++ b/script/vm/compiler.lua
@@ -15,7 +15,6 @@ local vm = require 'vm.vm'
---@field _node vm.node
---@field _localBase table
---@field _globalBase table
----@field _hasSorted boolean
local searchFieldSwitch = util.switch()
: case 'table'
@@ -870,51 +869,26 @@ local compilerSwitch = util.switch()
local hasMark = vm.getNode(source):getData 'hasDefined'
- if not source._hasSorted then
- source._hasSorted = true
- table.sort(refs, function (a, b)
- return (a.range or a.start) < (b.range or b.start)
- end)
- end
-
- local parentFunc = guide.getParentFunction(source)
-
- local index = 1
- local function runFunction(loc, currentFunc)
- while true do
- local ref = refs[index]
- if not ref then
- break
- end
- if ref.start > currentFunc.finish then
- break
- end
- local func = guide.getParentFunction(ref)
- if func == currentFunc then
- index = index + 1
- if ref.type == 'setlocal' then
- if ref.value and not hasMark then
- if ref.value.type == 'table' then
- vm.setNode(ref, ref.value)
- else
- vm.setNode(ref, vm.compileNode(ref.value))
- end
- else
- vm.setNode(ref, vm.getNode(loc))
- end
- loc = ref
- elseif ref.type == 'getlocal' then
- vm.setNode(ref, vm.getNode(loc), true)
+ local runner = vm.createRunner(source)
+ runner:launch(function (src, loc)
+ if src.type == 'setlocal' then
+ if src.value and not hasMark then
+ if src.value.type == 'table' then
+ vm.setNode(src, src.value)
+ else
+ vm.setNode(src, vm.compileNode(src.value))
end
else
- runFunction(loc, func)
+ vm.setNode(src, vm.getNode(loc))
end
+ loc = src
+ elseif src.type == 'getlocal' then
+ vm.setNode(src, vm.getNode(loc), true)
end
- end
-
- runFunction(source, parentFunc)
+ end)
if not hasMark then
+ local parentFunc = guide.getParentFunction(source)
for _, ref in ipairs(source.ref) do
if ref.type == 'setlocal'
and guide.getParentFunction(ref) == parentFunc then
diff --git a/script/vm/init.lua b/script/vm/init.lua
index 0058c698..61c52c65 100644
--- a/script/vm/init.lua
+++ b/script/vm/init.lua
@@ -8,5 +8,6 @@ require 'vm.field'
require 'vm.doc'
require 'vm.type'
require 'vm.library'
+require 'vm.local-compiler'
require 'vm.manager'
return vm
diff --git a/script/vm/local-compiler.lua b/script/vm/local-compiler.lua
new file mode 100644
index 00000000..6065229f
--- /dev/null
+++ b/script/vm/local-compiler.lua
@@ -0,0 +1,68 @@
+---@class vm
+local vm = require 'vm.vm'
+local guide = require 'parser.guide'
+
+---@class vm.local-compiler
+---@field loc parser.object
+---@field mainFunc parser.object
+local mt = {}
+mt.__index = mt
+mt.index = 1
+
+
+---@class parser.object
+---@field _hasSorted boolean
+
+---@param source parser.object
+local function sortRefs(source)
+ if source._hasSorted then
+ return
+ end
+ source._hasSorted = true
+ table.sort(source.ref, function (a, b)
+ return (a.range or a.start) < (b.range or b.start)
+ end)
+end
+
+---@param loc parser.object
+---@param currentFunc parser.object
+---@param callback fun(src: parser.object, loc: parser.object)
+function mt:_runFunction(loc, currentFunc, callback)
+ while true do
+ local ref = self.loc.ref[self.index]
+ if not ref then
+ break
+ end
+ if ref.start > currentFunc.finish then
+ break
+ end
+ local func = guide.getParentFunction(ref)
+ if func == currentFunc then
+ callback(ref, loc)
+ self.index = self.index + 1
+ if ref.type == 'setlocal' then
+ loc = ref
+ end
+ else
+ self:_runFunction(loc, func, callback)
+ end
+ end
+end
+
+---@param callback fun(src: parser.object, loc: parser.object)
+function mt:launch(callback)
+ self:_runFunction(self.loc, self.mainFunc, callback)
+end
+
+---@param loc parser.object
+---@return vm.local-compiler
+function vm.createRunner(loc)
+ local self = setmetatable({
+ loc = loc,
+ mainFunc = guide.getParentFunction(loc),
+ }, mt)
+
+ sortRefs(loc)
+
+ return self
+end