diff options
Diffstat (limited to 'script')
-rw-r--r-- | script/vm/literal-node.lua | 57 | ||||
-rw-r--r-- | script/vm/node/compiler.lua | 17 | ||||
-rw-r--r-- | script/vm/state.lua | 61 |
3 files changed, 72 insertions, 63 deletions
diff --git a/script/vm/literal-node.lua b/script/vm/literal-node.lua new file mode 100644 index 00000000..9c1f70a8 --- /dev/null +++ b/script/vm/literal-node.lua @@ -0,0 +1,57 @@ +local util = require 'utility' +local guide = require 'parser.guide' + +---@class vm.literal-node +local m = {} +---@type table<uri, parser.object[]> +m.literals = util.multiTable(2) +---@type table<parser.object, table<parser.object, boolean>> +m.literalSubs = util.multiTable(2, function () + return setmetatable({}, util.MODE_K) +end) +---@type table<parser.object, boolean> +m.allLiterals = {} + +---@param source parser.object +function m.declareLiteral(source) + if m.allLiterals[source] then + return + end + m.allLiterals[source] = true + local uri = guide.getUri(source) + local literals = m.literals[uri] + literals[#literals+1] = source +end + +---@param source parser.object +---@param node vm.node +function m.subscribeLiteral(source, node) + if not node then + return + end + if node.type == 'union' + or node.type == 'cross' then + node:subscribeLiteral(source) + return + end + if not m.allLiterals[source] then + return + end + m.literalSubs[node][source] = true +end + +---@param uri uri +function m.dropUri(uri) + local literals = m.literals[uri] + m.literals[uri] = nil + for _, literal in ipairs(literals) do + m.allLiterals[literal] = nil + local literalSubs = m.literalSubs[literal] + m.literalSubs[literal] = nil + for source in pairs(literalSubs) do + source._node = nil + end + end +end + +return m diff --git a/script/vm/node/compiler.lua b/script/vm/node/compiler.lua index dfe4bc0c..e8595ebf 100644 --- a/script/vm/node/compiler.lua +++ b/script/vm/node/compiler.lua @@ -1,8 +1,8 @@ -local guide = require 'parser.guide' -local util = require 'utility' -local state = require 'vm.state' -local union = require 'vm.node.union' -local localID = require 'vm.local-id' +local guide = require 'parser.guide' +local util = require 'utility' +local union = require 'vm.node.union' +local localID = require 'vm.local-id' +local literalNode = require 'vm.literal-node' ---@class parser.object ---@field _compiledNodes boolean @@ -119,7 +119,7 @@ local compilerMap = util.switch() : case 'string' : case 'function' : call(function (source) - m.setNode(source, state.declareLiteral(source)) + m.setNode(source, literalNode.declareLiteral(source)) end) : case 'local' : call(function (source) @@ -183,7 +183,10 @@ function m.compileNode(source) if compiler then compiler(source) end - state.subscribeLiteral(source, source._node) + literalNode.subscribeLiteral(source, source._node) + if source._globalNode then + m.setNode(source, source._globalNode) + end return source._node end diff --git a/script/vm/state.lua b/script/vm/state.lua index b0689384..901cf081 100644 --- a/script/vm/state.lua +++ b/script/vm/state.lua @@ -1,61 +1,10 @@ -local util = require 'utility' -local files = require 'files' -local globalNode = require 'vm.global-node' -local guide = require 'parser.guide' + +local files = require 'files' +local globalNode = require 'vm.global-node' +local literalNode = require 'vm.literal-node' ---@class vm.state local m = {} ----@type table<uri, parser.object[]> -m.literals = util.multiTable(2) ----@type table<parser.object, table<parser.object, boolean>> -m.literalSubs = util.multiTable(2, function () - return setmetatable({}, util.MODE_K) -end) ----@type table<parser.object, boolean> -m.allLiterals = {} - ----@param source parser.object -function m.declareLiteral(source) - if m.allLiterals[source] then - return - end - m.allLiterals[source] = true - local uri = guide.getUri(source) - local literals = m.literals[uri] - literals[#literals+1] = source -end - ----@param source parser.object ----@param node vm.node -function m.subscribeLiteral(source, node) - if not node then - return - end - if node.type == 'union' - or node.type == 'cross' then - node:subscribeLiteral(source) - return - end - if not m.allLiterals[source] then - return - end - m.literalSubs[node][source] = true -end - ----@param uri uri -function m.dropUri(uri) - local literals = m.literals[uri] - m.literals[uri] = nil - for _, literal in ipairs(literals) do - m.allLiterals[literal] = nil - local literalSubs = m.literalSubs[literal] - m.literalSubs[literal] = nil - for source in pairs(literalSubs) do - source._node = nil - end - end -end - for uri in files.eachFile() do local state = files.getState(uri) if state then @@ -71,8 +20,8 @@ files.watch(function (ev, uri) end end if ev == 'remove' then - m.dropUri(uri) globalNode.dropUri(uri) + literalNode.dropUri(uri) end end) |