summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/src/matcher/vm.lua85
-rw-r--r--server/test/vm/init.lua9
2 files changed, 47 insertions, 47 deletions
diff --git a/server/src/matcher/vm.lua b/server/src/matcher/vm.lua
index 53636be9..5c4736c9 100644
--- a/server/src/matcher/vm.lua
+++ b/server/src/matcher/vm.lua
@@ -30,7 +30,7 @@ function mt:createDots(source)
type = 'dots',
source = source or DefaultSource,
}
- self.func.dots = dots
+ self.chunk.dots = dots
return dots
end
@@ -112,33 +112,40 @@ function mt:createFunction(exp, object)
},
}
- if exp then
- local stop
- self:forList(exp.args, function (arg)
- if stop then
- return
- end
- if not func.args then
- func.args = {}
- end
- if arg.type == 'name' then
- func.args[#func.args+1] = self:createLocal(arg[1], arg)
- elseif arg.type == '...' then
- func.args[#func.args+1] = self:createDots(arg)
- stop = true
- end
- end)
+ if not exp then
+ return func
end
- if object then
- if not func.args then
- func.args = {}
+
+ self.scope:push()
+ self.chunk:push()
+ self.chunk:cut 'dots'
+ self.chunk:cut 'labels'
+
+ local stop
+ self:forList(exp.args, function (arg)
+ if stop then
+ return
+ end
+ if arg.type == 'name' then
+ self:createLocal(arg[1], arg)
+ elseif arg.type == '...' then
+ self:createDots(arg)
+ stop = true
end
- table.insert(func.args, 1, object)
+ end)
+ if object then
+ self:createLocal('self', object)
end
- self.func.func = func
+ self:doActions(exp)
+
+ self.chunk.func = func
self.results.funcs[#self.results.funcs+1] = func
self.newFuncs[#self.newFuncs+1] = func
+
+ self.chunk:pop()
+ self.scope:pop()
+
return func
end
@@ -159,11 +166,8 @@ function mt:call(func, values)
if func.used then
return self:getFunctionReturns(func)
end
+
func.used = true
- self.func:push()
- self.scope:push()
- self.func:cut 'labels'
- self.func:cut 'dots'
if func.args then
for i, var in ipairs(func.args) do
@@ -192,15 +196,11 @@ function mt:call(func, values)
end
end
- self:doActions(func)
-
- self.func:pop()
- self.scope:pop()
return self:getFunctionReturns(func)
end
function mt:getCurrentFunction()
- return self.func.func
+ return self.chunk.func
end
function mt:setFunctionReturn(index, value)
@@ -426,10 +426,10 @@ function mt:getUnary(exp)
end
function mt:getDots()
- if not self.func.dots then
+ if not self.chunk.dots then
self:createDots()
end
- return self.func.dots
+ return self.chunk.dots
end
function mt:getExp(exp)
@@ -479,15 +479,15 @@ end
function mt:createLabel(action)
local name = action[1]
- if not self.func.labels[name] then
+ if not self.chunk.labels[name] then
local label = {
type = 'label',
key = name,
}
- self.func.labels[name] = label
+ self.chunk.labels[name] = label
self.results.labels[#self.results.labels+1] = label
end
- return self.func.labels[name]
+ return self.chunk.labels[name]
end
function mt:doSet(action)
@@ -652,7 +652,7 @@ end
function mt:createEnvironment()
-- 整个文件是一个函数
- self.func.func = self:createFunction()
+ self.chunk.func = self:createFunction()
-- 隐藏的上值`_ENV`
local parent = self:createLocal('_ENV')
-- 隐藏的参数`...`
@@ -680,7 +680,7 @@ local function compile(ast)
scope = env {
locals = {},
},
- func = env {
+ chunk = env {
labels = {},
},
results = {
@@ -698,15 +698,6 @@ local function compile(ast)
-- 执行代码
vm:doActions(ast)
- -- 把所有没跑过的函数跑一遍(可能会创建新的函数,需要一直跑到没有新的函数为止)
- while true do
- local func = table.remove(vm.newFuncs, 1)
- if not func then
- break
- end
- vm:call(func)
- end
-
return vm.results
end
diff --git a/server/test/vm/init.lua b/server/test/vm/init.lua
index 6963e4c4..d8cfb3dc 100644
--- a/server/test/vm/init.lua
+++ b/server/test/vm/init.lua
@@ -114,3 +114,12 @@ TEST [[
local function xx(a, b, c, ...)
end
]]
+
+TEST [[
+local v = 1
+local function xx()
+ print(v)
+end
+local v = 2
+xx()
+]]