summaryrefslogtreecommitdiff
path: root/server-beta
diff options
context:
space:
mode:
Diffstat (limited to 'server-beta')
-rw-r--r--server-beta/src/brave/work.lua1
-rw-r--r--server-beta/src/core/engineer.lua36
-rw-r--r--server-beta/src/parser/compile.lua126
-rw-r--r--server-beta/src/parser/guide.lua35
-rw-r--r--server-beta/test/definition/set.lua5
5 files changed, 165 insertions, 38 deletions
diff --git a/server-beta/src/brave/work.lua b/server-beta/src/brave/work.lua
index edbb35f9..dba27808 100644
--- a/server-beta/src/brave/work.lua
+++ b/server-beta/src/brave/work.lua
@@ -23,6 +23,7 @@ brave.on('compile', function (text)
local lines = parser:lines(text)
return {
root = state.root,
+ value = state.value,
errs = state.errs,
lines = lines,
}
diff --git a/server-beta/src/core/engineer.lua b/server-beta/src/core/engineer.lua
index 45cff84e..073265db 100644
--- a/server-beta/src/core/engineer.lua
+++ b/server-beta/src/core/engineer.lua
@@ -30,10 +30,6 @@ function mt:eachRefAsLocal(obj, callback)
callback(self.root[ref], 'set')
elseif refObj.type == 'getlocal' then
callback(self.root[ref], 'get')
- elseif refObj.type == 'setglobal' then
- callback(self.root[ref], 'settable', refObj)
- elseif refObj.type == 'getglobal' then
- callback(self.root[ref], 'gettable', refObj)
end
end
end
@@ -43,24 +39,23 @@ end
function mt:eachRefAsGlobal(obj, callback)
local version = config.config.runtime.version
if version ~= 'Lua 5.1' and version ~= 'LuaJIT' then
- local env = guide.getLocal(self.root, obj, '_ENV', obj.start)
- local field = self:getFieldName(obj)
- self:eachRefAsField(env, field, callback)
+ self:eachRefAsField(obj, callback)
return
end
end
--- 查找所有域引用
-function mt:eachRefAsField(parent, field, callback)
- self:eachRef(parent, function (src, mode)
- if self:getFieldName(src) ~= field then
- return
- end
- if mode == 'settable' then
- callback(src, 'set')
- elseif mode == 'gettable' then
- callback(src, 'get')
- end
+function mt:eachRefAsField(obj, callback)
+ local nodeID = obj.node
+ if not nodeID then
+ return
+ end
+ local node = self.root[nodeID]
+ local key = guide.getKeyName(obj)
+ if not key then
+ return
+ end
+ guide.eachField(self.value, node, key, function ()
end)
end
@@ -81,9 +76,10 @@ return function (ast)
ast.vm = {}
end
local self = setmetatable({
- step = 0,
- root = ast.root,
- vm = ast.vm,
+ step = 0,
+ root = ast.root,
+ value = ast.value,
+ vm = ast.vm,
}, mt)
return self
end
diff --git a/server-beta/src/parser/compile.lua b/server-beta/src/parser/compile.lua
index 8cfcd7a2..b8abad22 100644
--- a/server-beta/src/parser/compile.lua
+++ b/server-beta/src/parser/compile.lua
@@ -3,7 +3,105 @@ local type = type
_ENV = nil
-local pushError, Root, Compile, CompileBlock, Cache, Block, GoToTag, Version, ENVMode
+local pushError, Root, Compile, CompileBlock, Cache, Block, GoToTag, Version, ENVMode, Value
+
+--[[
+-- value 类右字面量创建,在set get call中传递
+-- obj 用 vref 表标记当前可能的 value 是哪些
+Value
+ type -> 确定类型
+ literal -> 字面量对象
+ tag -> 特殊标记
+ ref -> 值的引用者
+ child -> 值的child
+ func -> 函数对象
+--]]
+
+local function createValue(data)
+ local id = #Value+1
+ Value[id] = data
+ data.ref = {}
+ return id
+end
+
+local function addValue(objID, valueID)
+ local obj = Root[objID]
+ local vref = obj.vref
+ if not vref then
+ vref = {}
+ obj.vref = vref
+ Cache[vref] = {}
+ end
+ local cache = Cache[vref]
+ if cache[valueID] then
+ return
+ end
+ cache[valueID] = true
+ vref[#vref+1] = valueID
+ local valueRef = Value[valueID].ref
+ valueRef[#valueRef+1] = objID
+end
+
+local function getValue(objID)
+ local obj = Root[objID]
+ local vref = obj.vref
+ if vref then
+ return vref
+ end
+ addValue(objID, createValue {})
+ return obj.vref
+end
+
+local function mergeValue(objID1, objID2)
+ local obj1 = Root[objID1]
+ local obj2 = Root[objID2]
+ local vref1 = obj1.vref
+ local vref2 = obj2.vref
+ if not vref2 then
+ return
+ end
+ if not vref1 then
+ vref1 = {}
+ obj1.vref = vref1
+ Cache[vref1] = {}
+ end
+ local cache = Cache[vref1]
+ for i = 1, #vref2 do
+ local valueID = vref2[i]
+ if not cache[valueID] then
+ cache[valueID] = true
+ vref1[#vref1+1] = valueID
+ local valueRef = Value[valueID].ref
+ valueRef[#valueRef+1] = objID1
+ end
+ end
+end
+
+local function setChildValue(objID, keyID, valueID)
+ if not valueID then
+ return
+ end
+ local objVref = getValue(objID)
+ local key = guide.getKeyName(Root[keyID])
+ local valueVref = getValue(valueID)
+ for i = 1, #objVref do
+ local value = Value[objVref[i]]
+ if not value.child then
+ value.child = {}
+ end
+ value.child[key] = valueVref
+ end
+end
+
+local function addLocalRef(nodeID, objID)
+ local node = Root[nodeID]
+ local obj = Root[objID]
+ if not node.ref then
+ node.ref = {}
+ end
+ node.ref[#node.ref+1] = objID
+ obj.node = nodeID
+end
local vmMap = {
['nil'] = function (obj)
@@ -40,13 +138,9 @@ local vmMap = {
else
obj.type = 'getglobal'
if ENVMode == '_ENV' then
- local node = guide.getLocal(Root, obj, '_ENV', obj.start)
+ local node, nodeID = guide.getLocal(Root, obj, '_ENV', obj.start)
if node then
- if not node.ref then
- node.ref = {}
- end
- node.ref[#node.ref+1] = id
- obj.node = Cache[node]
+ addLocalRef(nodeID, id)
end
end
end
@@ -278,13 +372,10 @@ local vmMap = {
else
obj.type = 'setglobal'
if ENVMode == '_ENV' then
- local node = guide.getLocal(Root, obj, '_ENV', obj.start)
+ local node, nodeID = guide.getLocal(Root, obj, '_ENV', obj.start)
if node then
- if not node.ref then
- node.ref = {}
- end
- node.ref[#node.ref+1] = id
- obj.node = Cache[node]
+ addLocalRef(nodeID, id)
+ setChildValue(nodeID, id, obj.value)
end
end
end
@@ -508,13 +599,17 @@ local vmMap = {
Root[#Root+1] = obj
local id = #Root
if ENVMode == '_ENV' then
- Compile({
+ local envID = Compile({
type = 'local',
start = 0,
finish = 0,
effect = 0,
[1] = '_ENV',
}, id)
+ addValue(envID, createValue {
+ type = 'table',
+ tag = '_ENV',
+ })
end
CompileBlock(obj, id)
Block = nil
@@ -633,11 +728,14 @@ return function (self, lua, mode, version)
end
Cache = {}
GoToTag = {}
+ Value = {}
if type(state.ast) == 'table' then
Compile(state.ast)
end
PostCompile()
state.ast = nil
+ state.value = Value
Cache = nil
+ Value = nil
return state
end
diff --git a/server-beta/src/parser/guide.lua b/server-beta/src/parser/guide.lua
index 7925abe2..747d8d4f 100644
--- a/server-beta/src/parser/guide.lua
+++ b/server-beta/src/parser/guide.lua
@@ -129,18 +129,19 @@ function m.getLocal(root, block, name, pos)
goto CONTINUE
end
for i = 1, #locals do
- local loc = root[locals[i]]
+ local locID = locals[i]
+ local loc = root[locID]
if loc.effect > pos then
break
end
if loc[1] == name then
- if not res or res.effect < loc.effect then
- res = loc
+ if not res or root[res].effect < loc.effect then
+ res = locID
end
end
end
if res then
- return res
+ return root[res], res
end
::CONTINUE::
block = m.getParentBlock(root, block)
@@ -286,4 +287,30 @@ function m.lineRange(lines, row)
return line.start + 1, line.finish
end
+function m.getKeyName(obj)
+ if obj.type == 'getglobal' or obj.type == 'setglobal' then
+ return 'string|' .. obj[1]
+ elseif obj.type == 'getfield' or obj.type == 'getglobal' then
+ return 'string|' .. obj[1]
+ end
+end
+
+function m.eachField(value, obj, key, callback)
+ local vref = obj.vref
+ if not vref then
+ return
+ end
+ for x = 1, #vref do
+ local vID = vref[x]
+ local v = value[vID]
+ local child = v.child
+ if child then
+ local refs = child[key]
+ if refs then
+
+ end
+ end
+ end
+end
+
return m
diff --git a/server-beta/test/definition/set.lua b/server-beta/test/definition/set.lua
index b7e7e5d4..be653baa 100644
--- a/server-beta/test/definition/set.lua
+++ b/server-beta/test/definition/set.lua
@@ -40,6 +40,11 @@ print(<?x?>)
]]
TEST [[
+<!_ENV.x!> = 1
+print(<?x?>)
+]]
+
+TEST [[
<!_G.x!> = 1
print(<?x?>)
]]