diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/src/vm/dots.lua | 2 | ||||
-rw-r--r-- | server/src/vm/function.lua | 87 | ||||
-rw-r--r-- | server/src/vm/library.lua | 6 | ||||
-rw-r--r-- | server/src/vm/source.lua | 4 | ||||
-rw-r--r-- | server/src/vm/value.lua | 4 | ||||
-rw-r--r-- | server/src/vm/vm.lua | 89 | ||||
-rw-r--r-- | server/test/full/dirty.lua (renamed from server/test/vm/dirty.lua) | 0 | ||||
-rw-r--r-- | server/test/full/example.lua (renamed from server/test/vm/example.lua) | 2 | ||||
-rw-r--r-- | server/test/full/init.lua | 15 | ||||
-rw-r--r-- | server/test/full/normal.lua (renamed from server/test/vm/normal.lua) | 0 | ||||
-rw-r--r-- | server/test/main.lua | 2 | ||||
-rw-r--r-- | server/test/vm/init.lua | 17 |
12 files changed, 138 insertions, 90 deletions
diff --git a/server/src/vm/dots.lua b/server/src/vm/dots.lua index 1736de5c..db8e134e 100644 --- a/server/src/vm/dots.lua +++ b/server/src/vm/dots.lua @@ -3,4 +3,6 @@ mt.__index = mt mt.type = 'dots' return function () + local self = setmetatable({}, mt) + return self end diff --git a/server/src/vm/function.lua b/server/src/vm/function.lua index 25465398..90f975ae 100644 --- a/server/src/vm/function.lua +++ b/server/src/vm/function.lua @@ -4,7 +4,7 @@ local createDots = require 'vm.dots' local mt = {} mt.__index = mt mt.type = 'function' -mt._returnDots = false +mt._runed = 0 function mt:getUri() return self.source.uri @@ -14,23 +14,94 @@ function mt:saveLocal(name, loc) self.locals[name] = loc end +function mt:loadLocal(name) + local loc = self.locals[name] + if loc then + return loc + end + loc = self.upvalues(name) + if loc then + return loc + end + return nil +end + +function mt:eachLocal(callback) + for name, loc in pairs(self.locals) do + local res = callback(name, loc) + if res ~= nil then + return res + end + end + return nil +end + function mt:setReturn(index, value) + if not self.returns then + self.returns = {} + end self.returns[index] = value end -function mt:returnDots(index, value) - self.returns[index] = value - self._returnDots = true +function mt:returnDots(index) + if not self.returns then + self.returns = {} + end + self.returns[index] = createDots() end -return function (source) - if not source then - error('Function must has a source') +function mt:hasRuned() + return self._runed > 0 +end + +function mt:run() + self._runed = self._runed + 1 + if not self.source then + return end + + --local index = 0 + --if func.object then + -- local var = self:createArg('self', func.colon, self:getValue--(func.object, func.colon)) + -- var.hide = true + -- var.link = func.object + -- if func.argValues[1] then + -- self:setValue(var, func.argValues[1]) + -- end + -- index = 1 + -- func.args[index] = var + --end + + local stop + self:forList(func.built.arg, function (arg) + if stop then + return + end + index = index + 1 + if arg.type == 'name' then + local var = self:createArg(arg[1], arg) + self:setValue(var, func.argValues[index] or self:createValue('nil')) + func.args[index] = var + elseif arg.type == '...' then + local dots = self:createDots(index, arg) + for i = index, #func.argValues do + dots[#dots+1] = func.argValues[i] + end + func.hasDots = true + stop = true + end + end) +end + +function mt:saveUpvalues(name, loc) + self.upvalues[name] = loc +end + +return function (source) local self = setmetatable({ source = source, locals = {}, - returns = {}, + upvalues = {}, }, mt) return self end diff --git a/server/src/vm/library.lua b/server/src/vm/library.lua index a6b9629e..bf18d177 100644 --- a/server/src/vm/library.lua +++ b/server/src/vm/library.lua @@ -19,12 +19,12 @@ function buildLibValue(lib) value = createValue('table') elseif tp == 'function' then value = createValue('function') - local func = createFunction(getDefaultSource()) + local func = createFunction() value:setFunction(func) if lib.returns then for i, rtn in ipairs(lib.returns) do if rtn.type == '...' then - func:returnDots(i, buildLibValue(rtn)) + func:returnDots(i) else func:setReturn(i, buildLibValue(rtn)) end @@ -40,8 +40,6 @@ function buildLibValue(lib) value = createValue('integer') elseif tp == 'nil' then value = createValue('nil') - elseif tp == '...' then - value = createValue('any') else value = createValue(tp or 'any') end diff --git a/server/src/vm/source.lua b/server/src/vm/source.lua index 5ec602c6..b4539ae5 100644 --- a/server/src/vm/source.lua +++ b/server/src/vm/source.lua @@ -13,6 +13,10 @@ function mt:setUri(uri) self._uri = uri end +function mt:getUri() + return self._uri +end + return function (source) return setmetatable(source, mt) end diff --git a/server/src/vm/value.lua b/server/src/vm/value.lua index 21dd4307..f8824db6 100644 --- a/server/src/vm/value.lua +++ b/server/src/vm/value.lua @@ -205,6 +205,10 @@ function mt:setFunction(func) self:setType('function', 1.0) end +function mt:getFunction() + return self._func +end + function mt:setLib(lib) self._lib = lib end diff --git a/server/src/vm/vm.lua b/server/src/vm/vm.lua index 48d7e038..4c1ce526 100644 --- a/server/src/vm/vm.lua +++ b/server/src/vm/vm.lua @@ -227,67 +227,18 @@ function mt:isGlobal(field) return field.GLOBAL == true end -function mt:callLeftFuncions() - for _, func in ipairs(self.results.funcs) do - if func.built and not func.runed then - self:runFunction(func) - end - end -end - function mt:runFunction(func) - func.runed = (func.runed or 0) + 1 - if func.runed > 1 then - --return - end - self:scopePush(func.built) - self.chunk:push() - self.chunk:cut 'dots' - self.chunk:cut 'labels' - self.chunk:cut 'locals' - self.chunk.func = func - - self.scope:cut 'locals' - for name, loc in pairs(func.upvalues) do - self.scope.locals[name] = loc - end - - local index = 0 - if func.object then - local var = self:createArg('self', func.colon, self:getValue(func.object, func.colon)) - var.hide = true - var.link = func.object - if func.argValues[1] then - self:setValue(var, func.argValues[1]) - end - index = 1 - func.args[index] = var + func:run() + + if not func.source then + return end - local stop - self:forList(func.built.arg, function (arg) - if stop then - return - end - index = index + 1 - if arg.type == 'name' then - local var = self:createArg(arg[1], arg) - self:setValue(var, func.argValues[index] or self:createValue('nil')) - func.args[index] = var - elseif arg.type == '...' then - local dots = self:createDots(index, arg) - for i = index, #func.argValues do - dots[#dots+1] = func.argValues[i] - end - func.hasDots = true - stop = true - end - end) + local originFunction = self:getCurrentFunction() - self:doActions(func.built) + self:doActions(func.source) - self.chunk:pop() - self:scopePop() + self:setCurrentFunction(originFunction) end function mt:buildFunction(exp, object, colon) @@ -1202,7 +1153,6 @@ function mt:doAction(action) -- Skip return end - action.uri = self.chunk.func.uri local tp = action.type if tp == 'do' then self:doDo(action) @@ -1264,14 +1214,34 @@ function mt:createFunction(source) return value end -function mt:setCurrentFunction(func) - self.currentFunction = func +function mt:callLeftFuncions() + for _, func in ipairs(self.funcs) do + if not func:hasRuned() then + self:runFunction(func) + end + end +end + +function mt:setCurrentFunction(value) + self.currentFunction = value:getFunction() +end + +function mt:getCurrentFunction() + return self.currentFunction end function mt:saveLocal(name, loc) self.currentFunction:saveLocal(name, loc) end +function mt:loadLocal(name) + return self.currentFunction:loadLocal(name) +end + +function mt:eachLocal(callback) + return self.currentFunction:eachLocal(callback) +end + function mt:getUri() return self.currentFunction:getUri() end @@ -1337,6 +1307,7 @@ local function compile(ast, lsp, uri) -- 创建初始环境 ast.uri = vm.uri + vm:instantSource(ast) vm:createEnvironment(ast) -- 检查所有没有调用过的函数,调用一遍 diff --git a/server/test/vm/dirty.lua b/server/test/full/dirty.lua index 9c2e65fb..9c2e65fb 100644 --- a/server/test/vm/dirty.lua +++ b/server/test/full/dirty.lua diff --git a/server/test/vm/example.lua b/server/test/full/example.lua index 9a2939b5..321f3bc7 100644 --- a/server/test/vm/example.lua +++ b/server/test/full/example.lua @@ -1,6 +1,6 @@ local fs = require 'bee.filesystem' -TEST(io.load(ROOT / 'src' / 'core' / 'vm.lua')) +TEST(io.load(ROOT / 'src' / 'vm' / 'vm.lua')) -- 临时 local function testIfExit(path) diff --git a/server/test/full/init.lua b/server/test/full/init.lua new file mode 100644 index 00000000..f3a7402d --- /dev/null +++ b/server/test/full/init.lua @@ -0,0 +1,15 @@ +local buildVM = require 'vm' +local parser = require 'parser' + +rawset(_G, 'TEST', true) + +function TEST(script) + local ast = parser:ast(script) + assert(ast) + local vm = buildVM(ast) + assert(vm) +end + +require 'full.normal' +require 'full.example' +require 'full.dirty' diff --git a/server/test/vm/normal.lua b/server/test/full/normal.lua index 02b1f4f0..02b1f4f0 100644 --- a/server/test/vm/normal.lua +++ b/server/test/full/normal.lua diff --git a/server/test/main.lua b/server/test/main.lua index 8738002c..7a498929 100644 --- a/server/test/main.lua +++ b/server/test/main.lua @@ -25,7 +25,7 @@ local function main() end test 'core' - test 'vm' + test 'full' test 'definition' test 'diagnostics' test 'type_inference' diff --git a/server/test/vm/init.lua b/server/test/vm/init.lua deleted file mode 100644 index 6e7dc3ac..00000000 --- a/server/test/vm/init.lua +++ /dev/null @@ -1,17 +0,0 @@ -local core = require 'core' -local parser = require 'parser' - -rawset(_G, 'TEST', true) - -function TEST(script) - local ast = parser:ast(script) - assert(ast) - local vm = core.vm(ast) - assert(vm) - local results = vm.results - assert(results) -end - -require 'vm.normal' -require 'vm.example' -require 'vm.dirty' |