diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2022-04-19 02:31:50 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2022-04-19 02:31:50 +0800 |
commit | fa191ea61477047c4754b730f129f96239ddb93e (patch) | |
tree | 84c9f60d23c82960b72f3a526bdd3aeeaadf46b1 /script/vm | |
parent | 9b91ebedd8ede80fcd0c001fffe96d2a10e41b39 (diff) | |
download | lua-language-server-fa191ea61477047c4754b730f129f96239ddb93e.zip |
cleanup
Diffstat (limited to 'script/vm')
-rw-r--r-- | script/vm/compiler.lua | 54 | ||||
-rw-r--r-- | script/vm/init.lua | 1 | ||||
-rw-r--r-- | script/vm/local-compiler.lua | 68 |
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 |