summaryrefslogtreecommitdiff
path: root/script/vm
diff options
context:
space:
mode:
Diffstat (limited to 'script/vm')
-rw-r--r--script/vm/getDef.lua28
-rw-r--r--script/vm/node/compiler.lua23
-rw-r--r--script/vm/node/global.lua28
-rw-r--r--script/vm/state.lua6
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