diff options
Diffstat (limited to 'script')
-rw-r--r-- | script/vm/compiler.lua | 94 | ||||
-rw-r--r-- | script/vm/def.lua | 2 | ||||
-rw-r--r-- | script/vm/local-id.lua | 38 | ||||
-rw-r--r-- | script/vm/node.lua | 1 | ||||
-rw-r--r-- | script/vm/ref.lua | 4 | ||||
-rw-r--r-- | script/vm/visible.lua | 2 |
6 files changed, 89 insertions, 52 deletions
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua index c8323a49..2cb2d93c 100644 --- a/script/vm/compiler.lua +++ b/script/vm/compiler.lua @@ -66,7 +66,7 @@ end local function searchFieldByLocalID(source, key, pushResult) local fields if key then - fields = vm.getLocalSourcesSets(source, key) + fields = vm.getLocalSets(source, key) else fields = vm.getLocalFields(source, false) end @@ -1234,42 +1234,72 @@ local compilerSwitch = util.switch() if key == nil then return end - if type(key) == 'table' then - ---@cast key vm.node - local uri = guide.getUri(source) - local value = vm.getTableValue(uri, vm.compileNode(source.node), key) - if value then - vm.setNode(source, value) - end - for k in key:eachObject() do - if k.type == 'global' and k.cate == 'type' then - ---@cast k vm.global - vm.compileByParentNode(source.node, k, function (src) - vm.setNode(source, vm.compileNode(src)) - if src.value then - vm.setNode(source, vm.compileNode(src.value)) - end - end) + + ---@type vm.node, boolean + local cacheNode, needCompile + + do + local localInfo = vm.getLocalInfo(source) + if localInfo then + cacheNode = localInfo.node + if not cacheNode then + needCompile = true + cacheNode = vm.createNode() + localInfo.node = cacheNode + end + else + local parentNode = vm.compileNode(source.node) + if not parentNode.fields then + parentNode.fields = {} + end + cacheNode = parentNode.fields[key] + if not cacheNode then + needCompile = true + cacheNode = vm.createNode() + parentNode.fields[key] = cacheNode end end - else - ---@cast key string - vm.compileByParentNode(source.node, key, function (src) - if src.value then - if bindDocs(src) then - vm.setNode(source, vm.compileNode(src)) - elseif src.value.type ~= 'nil' then - vm.setNode(source, vm.compileNode(src.value)) - local node = vm.getNode(src) - if node then - vm.setNode(source, node) - end + end + + if needCompile then + if type(key) == 'table' then + ---@cast key vm.node + local uri = guide.getUri(source) + local value = vm.getTableValue(uri, vm.compileNode(source.node), key) + if value then + cacheNode:merge(value) + end + for k in key:eachObject() do + if k.type == 'global' and k.cate == 'type' then + ---@cast k vm.global + vm.compileByParentNode(source.node, k, function (src) + cacheNode:merge(vm.compileNode(src)) + if src.value then + cacheNode:merge(vm.compileNode(src.value)) + end + end) end - else - vm.setNode(source, vm.compileNode(src)) end - end) + else + ---@cast key string + vm.compileByParentNode(source.node, key, function (src) + if src.value then + if bindDocs(src) then + cacheNode:merge(vm.compileNode(src)) + elseif src.value.type ~= 'nil' then + cacheNode:merge(vm.compileNode(src.value)) + local node = vm.getNode(src) + if node then + cacheNode:merge(node) + end + end + else + cacheNode:merge(vm.compileNode(src)) + end + end) + end end + vm.setNode(source, cacheNode) end) : case 'setglobal' : call(function (source) diff --git a/script/vm/def.lua b/script/vm/def.lua index 9bc6159b..09b7193f 100644 --- a/script/vm/def.lua +++ b/script/vm/def.lua @@ -33,7 +33,7 @@ end ---@param source parser.object ---@param pushResult fun(src: parser.object) local function searchByLocalID(source, pushResult) - local idSources = vm.getLocalSourcesSets(source) + local idSources = vm.getLocalSets(source) if not idSources then return end diff --git a/script/vm/local-id.lua b/script/vm/local-id.lua index 1c3fd356..89466c47 100644 --- a/script/vm/local-id.lua +++ b/script/vm/local-id.lua @@ -3,9 +3,14 @@ local guide = require 'parser.guide' ---@class vm local vm = require 'vm.vm' +---@class vm.local +---@field sets parser.object[] +---@field gets parser.object[] +---@field node? vm.node + ---@class parser.object ---@field package _localID string|false ----@field package _localIDs table<string, { sets: parser.object[], gets: parser.object[] }> +---@field package _localIDs table<string, vm.local> local compileLocalID, getLocal @@ -163,8 +168,8 @@ end ---@param source parser.object ---@param key? string ----@return parser.object[]? -function vm.getLocalSourcesSets(source, key) +---@return vm.local? +function vm.getLocalInfo(source, key) local id = vm.getLocalID(source) if not id then return nil @@ -179,28 +184,29 @@ function vm.getLocalSourcesSets(source, key) end id = id .. vm.ID_SPLITE .. key end - return root._localIDs[id].sets + return root._localIDs[id] end ---@param source parser.object ---@param key? string ---@return parser.object[]? -function vm.getLocalSourcesGets(source, key) - local id = vm.getLocalID(source) - if not id then +function vm.getLocalSets(source, key) + local localInfo = vm.getLocalInfo(source, key) + if not localInfo then return nil end - local root = guide.getRoot(source) - if not root._localIDs then + return localInfo.sets +end + +---@param source parser.object +---@param key? string +---@return parser.object[]? +function vm.getLocalGets(source, key) + local localInfo = vm.getLocalInfo(source, key) + if not localInfo then return nil end - if key then - if type(key) ~= 'string' then - return nil - end - id = id .. vm.ID_SPLITE .. key - end - return root._localIDs[id].gets + return localInfo.gets end ---@param source parser.object diff --git a/script/vm/node.lua b/script/vm/node.lua index 65d752df..ec1b9ef2 100644 --- a/script/vm/node.lua +++ b/script/vm/node.lua @@ -14,6 +14,7 @@ vm.nodeCache = setmetatable({}, util.MODE_K) ---@class vm.node ---@field [integer] vm.node.object ---@field [vm.node.object] true +---@field fields? table<vm.node|string, vm.node> local mt = {} mt.__index = mt mt.id = 0 diff --git a/script/vm/ref.lua b/script/vm/ref.lua index 012cfd28..45c01c78 100644 --- a/script/vm/ref.lua +++ b/script/vm/ref.lua @@ -228,13 +228,13 @@ end ---@param source parser.object ---@param pushResult fun(src: parser.object) local function searchByLocalID(source, pushResult) - local sourceSets = vm.getLocalSourcesSets(source) + local sourceSets = vm.getLocalSets(source) if sourceSets then for _, src in ipairs(sourceSets) do pushResult(src) end end - local sourceGets = vm.getLocalSourcesGets(source) + local sourceGets = vm.getLocalGets(source) if sourceGets then for _, src in ipairs(sourceGets) do pushResult(src) diff --git a/script/vm/visible.lua b/script/vm/visible.lua index 0a0144b7..485063f8 100644 --- a/script/vm/visible.lua +++ b/script/vm/visible.lua @@ -76,7 +76,7 @@ end ---@return vm.global? function vm.getDefinedClass(suri, source) source = guide.getSelfNode(source) or source - local sets = vm.getLocalSourcesSets(source) + local sets = vm.getLocalSets(source) if sets then for _, set in ipairs(sets) do if set.bindDocs then |