summaryrefslogtreecommitdiff
path: root/script/vm/node/compiler.lua
diff options
context:
space:
mode:
Diffstat (limited to 'script/vm/node/compiler.lua')
-rw-r--r--script/vm/node/compiler.lua73
1 files changed, 49 insertions, 24 deletions
diff --git a/script/vm/node/compiler.lua b/script/vm/node/compiler.lua
index 71d872b8..422f464e 100644
--- a/script/vm/node/compiler.lua
+++ b/script/vm/node/compiler.lua
@@ -1,20 +1,21 @@
-local guide = require 'parser.guide'
-local util = require 'utility'
-local state = require 'vm.state'
+local guide = require 'parser.guide'
+local util = require 'utility'
+local state = require 'vm.state'
+local union = require 'vm.node.union'
---@class parser.object
---@field _compiledNodes boolean
----@field _compiled any
+---@field _node vm.node
---@field _globalID vm.node.global
---@class vm.node.compiler
local m = {}
----@class vm.node.unknown
-m.UNKNOWN = { type = 'unknown' }
+---@class vm.node.cross
+
m.GLOBAL_SPLITE = '\x1F'
----@alias vm.node vm.node.unknown | vm.node.global | vm.node.class
+---@alias vm.node parser.object | vm.node.union | vm.node.cross
---@param ... string
---@return string
@@ -22,26 +23,49 @@ function m.getGlobalID(...)
return table.concat({...}, m.GLOBAL_SPLITE)
end
+function m.setNode(source, node)
+ local me = source._node
+ if not me then
+ source._node = node
+ return
+ end
+ if me.type == 'union'
+ or me.type == 'cross' then
+ me:merge(source, node)
+ return
+ end
+ source._node = union(source, node)
+end
+
+local function compileValue(uri, source, value)
+ if not value then
+ return
+ end
+ if value.type == 'table'
+ or value.type == 'integer'
+ or value.type == 'number'
+ or value.type == 'string'
+ or value.type == 'function' then
+ state.declareLiteral(uri, value)
+ m.setNode(source, value)
+ end
+end
+
local compilerMap = util.switch()
: case 'local'
: call(function (uri, source)
- local value = source.value
- if not value then
- return
- end
- if value.type == 'table'
- or value.type == 'integer'
- or value.type == 'number'
- or value.type == 'string'
- or value.type == 'function' then
- source._compiled = value
- state.declareLiteral(uri, value)
- state.subscribeLiteral(value, source)
+ compileValue(uri, source, source.value)
+ if source.ref then
+ for _, ref in ipairs(source.ref) do
+ if ref.type == 'setlocal' then
+ compileValue(uri, source, ref.value)
+ end
+ end
end
end)
: case 'getlocal'
: call(function (uri, source)
- source._compiled = m.compileNode(uri, source.node)
+ m.setNode(source, m.compileNode(uri, source.node))
end)
: getMap()
@@ -49,15 +73,16 @@ local compilerMap = util.switch()
---@param source parser.object
---@return vm.node
function m.compileNode(uri, source)
- if source._compiled then
- return source._compiled
+ if source._node then
+ return source._node
end
- source._compiled = m.UNKNOWN
+ source._node = false
local compiler = compilerMap[source.type]
if compiler then
compiler(uri, source)
end
- return source._compiled
+ state.subscribeLiteral(source, source._node)
+ return source._node
end
local compilerGlobalMap = util.switch()