diff options
Diffstat (limited to 'script/vm')
-rw-r--r-- | script/vm/getDef.lua | 28 | ||||
-rw-r--r-- | script/vm/node/compiler.lua | 23 | ||||
-rw-r--r-- | script/vm/node/global.lua | 28 | ||||
-rw-r--r-- | script/vm/state.lua | 6 |
4 files changed, 76 insertions, 9 deletions
diff --git a/script/vm/getDef.lua b/script/vm/getDef.lua index 11a64421..d3c6c456 100644 --- a/script/vm/getDef.lua +++ b/script/vm/getDef.lua @@ -1,7 +1,8 @@ -local util = require 'utility' - ---@class vm -local vm = require 'vm.vm' +local vm = require 'vm.vm' +local util = require 'utility' +local compiler = require 'vm.node.compiler' +local guide = require 'parser.guide' local simpleMap = util.switch() : case 'local' @@ -15,12 +16,33 @@ local simpleMap = util.switch() end) : getMap() +local noderMap = util.switch() + : case 'global' + ---@param node vm.node.global + : call(function (node, results) + for _, set in ipairs(node:getSets()) do + results[#results+1] = set + end + end) + : getMap() + function vm.getDefs(source, field) local results = {} + + -- search by simple local simple = simpleMap[source.type] if simple then simple(source, results) end + local uri = guide.getUri(source) + + -- search by node + local node = compiler.compileNode(uri, source) + local noder = noderMap[node.type] + if noder then + noder(node, results) + end + return results end diff --git a/script/vm/node/compiler.lua b/script/vm/node/compiler.lua index 2663291c..3c7466b5 100644 --- a/script/vm/node/compiler.lua +++ b/script/vm/node/compiler.lua @@ -1,4 +1,4 @@ -local guide = require 'guide' +local guide = require 'parser.guide' local util = require 'utility' local state = require 'vm.state' @@ -13,27 +13,36 @@ local m = {} ---@class vm.node.unknown m.UNKNOWN = { type = 'unknown' } +---@alias vm.node vm.node.unknown | vm.node.global | vm.node.class + local compilerMap = util.switch() : case 'setglobal' : call(function (uri, source) - state.declareGlobal(source[1], uri, source) + local name = guide.getKeyName(source) + source._compiled = state.declareGlobal(name, uri, source) end) + : case 'getglobal' : call(function (uri, source) - local global = state.getGlobal(source[1]) + local name = guide.getKeyName(source) + local global = state.getGlobal(name) global:addGet(uri, source) + source._compiled = global end) + : getMap() ---@param uri uri ---@param source parser.guide.object +---@return vm.node function m.compileNode(uri, source) if source._compiled then - return + return source._compiled end source._compiled = m.UNKNOWN local compiler = compilerMap[source.type] if compiler then compiler(uri, source) end + return source._compiled end ---编译全局变量的node @@ -48,8 +57,10 @@ function m.compileGlobals(root) root._compiledGlobals = true local uri = guide.getUri(root) local env = guide.getENV(root) - for _, ref in ipairs(env.refs) do - m.compileNode(uri, ref) + if env.ref then + for _, ref in ipairs(env.ref) do + m.compileNode(uri, ref) + end end end diff --git a/script/vm/node/global.lua b/script/vm/node/global.lua index 07fff2d3..ebb06731 100644 --- a/script/vm/node/global.lua +++ b/script/vm/node/global.lua @@ -2,6 +2,8 @@ local util = require 'utility' ---@class vm.node.global ---@field links table<uri, { gets: table, sets: table }> +---@field setsCache parser.guide.object[] +---@field getsCache parser.guide.object[] local mt = {} mt.__index = mt mt.type = 'global' @@ -17,8 +19,34 @@ function mt:addGet(uri, source) link.gets[#link.gets+1] = source end +function mt:getSets() + if not self.setsCache then + self.setsCache = {} + for _, link in pairs(self.links) do + for _, source in ipairs(link.sets) do + self.setsCache[#self.setsCache+1] = source + end + end + end + return self.setsCache +end + +function mt:getGets() + if not self.getsCache then + self.getsCache = {} + for _, link in pairs(self.links) do + for _, source in ipairs(link.gets) do + self.getsCache[#self.getsCache+1] = source + end + end + end + return self.getsCache +end + function mt:dropUri(uri) self.links[uri] = nil + self.setsCache = nil + self.setsCache = nil end ---@return vm.node.global diff --git a/script/vm/state.lua b/script/vm/state.lua index ba0b6665..44b62684 100644 --- a/script/vm/state.lua +++ b/script/vm/state.lua @@ -13,6 +13,9 @@ m.subscriptions = util.defaultTable(function () } end) +---@param name string +---@param uri uri +---@param source parser.guide.object ---@return vm.node.global function m.declareGlobal(name, uri, source) m.subscriptions[uri].globals[name] = true @@ -21,6 +24,8 @@ function m.declareGlobal(name, uri, source) return node end +---@param name string +---@param uri? uri ---@return vm.node.global function m.getGlobal(name, uri) if uri then @@ -29,6 +34,7 @@ function m.getGlobal(name, uri) return m.globals[name] end +---@param uri uri function m.dropUri(uri) local subscription = m.subscriptions[uri] m.subscriptions[uri] = nil |