diff options
Diffstat (limited to 'server/src/vm')
-rw-r--r-- | server/src/vm/function.lua | 32 | ||||
-rw-r--r-- | server/src/vm/library.lua | 5 | ||||
-rw-r--r-- | server/src/vm/source.lua | 9 | ||||
-rw-r--r-- | server/src/vm/value.lua | 8 | ||||
-rw-r--r-- | server/src/vm/vm.lua | 17 |
5 files changed, 55 insertions, 16 deletions
diff --git a/server/src/vm/function.lua b/server/src/vm/function.lua index a6835f5b..145e5eda 100644 --- a/server/src/vm/function.lua +++ b/server/src/vm/function.lua @@ -125,6 +125,10 @@ function mt:setObject(value, source) self._objectSource = source end +function mt:getObject() + return self._objectValue, self._objectSource +end + function mt:hasRuned() return self._runed > 0 end @@ -135,6 +139,10 @@ function mt:run() return end + if self._runed > 1 then + --return + end + -- 第一次运行函数时,创建函数的参数 if self._runed ~= 1 then return @@ -157,22 +165,33 @@ function mt:setArgs(values) for i = 1, #values do self.argValues[i] = values[i] end - if self.dots then - local dotsIndex = #self.args - for i = dotsIndex, #values do - self.dots:set(i - dotsIndex + 1, values[i]) - end - end end function mt:createArg(arg) if arg.type == 'name' then local loc = createLocal(arg[1], arg, createValue('any', arg)) self:saveLocal(arg[1], loc) + self.args[#self.args+1] = loc elseif arg.type == '...' then + self._dots = createDots() end end +function mt:createLibArg(arg) + if arg.type == '...' then + self._dots = createDots() + else + local name = arg.name or '_' + local loc = createLocal(name, nil, createValue('any')) + self:saveLocal(name, loc) + self.args[#self.args+1] = loc + end +end + +function mt:hasDots() + return self._dots ~= nil +end + function mt:createArgs() if not self.source then return @@ -194,6 +213,7 @@ return function (source) local self = setmetatable({ source = source, locals = {}, + args = {}, }, mt) self:push() return self diff --git a/server/src/vm/library.lua b/server/src/vm/library.lua index 263b8d73..4545b1b5 100644 --- a/server/src/vm/library.lua +++ b/server/src/vm/library.lua @@ -15,6 +15,11 @@ function buildLibValue(lib) value = createValue('function') local func = createFunction() value:setFunction(func) + if lib.args then + for _, arg in ipairs(lib.args) do + func:createLibArg(arg) + end + end if lib.returns then for i, rtn in ipairs(lib.returns) do if rtn.type == '...' then diff --git a/server/src/vm/source.lua b/server/src/vm/source.lua index 6685b95f..a06b8e8a 100644 --- a/server/src/vm/source.lua +++ b/server/src/vm/source.lua @@ -40,6 +40,15 @@ function mt:bindValue(value, action) end end +function mt:bindCall(func, args) + if func then + self._bindCall = func + self._bindCallArgs = args + else + return self._bindCall, self._bindCallArgs + end +end + function mt:action() return self._action end diff --git a/server/src/vm/value.lua b/server/src/vm/value.lua index 0f2a8193..66f15da2 100644 --- a/server/src/vm/value.lua +++ b/server/src/vm/value.lua @@ -167,8 +167,14 @@ function mt:mergeValue(value) self._child[k] = v end end + local hasSource = {} + for _, info in ipairs(self) do + hasSource[info.source] = true + end for _, info in ipairs(value) do - self[#self+1] = info + if not hasSource[info.source] then + self[#self+1] = info + end end if value._meta then self._meta = value._meta diff --git a/server/src/vm/vm.lua b/server/src/vm/vm.lua index 1113a083..9e19199e 100644 --- a/server/src/vm/vm.lua +++ b/server/src/vm/vm.lua @@ -314,15 +314,15 @@ function mt:call(value, values, source) end end else - if not func.built then + if not func.source then func:setReturn(1, self:createValue('any', source)) end end - if not source.hasRuned and func.built then + if not source.hasRuned and func.source then source.hasRuned = true func:setArgs(values) - self:runFunction(value) + self:runFunction(func) end return func:getReturn() @@ -473,6 +473,7 @@ function mt:getSimple(simple, max) if object then table.insert(args, 1, object) end + source:bindCall(func, args) value = self:call(func, args, source) or createValue('any') elseif source.type == 'index' then local child = source[1] @@ -503,8 +504,8 @@ end function mt:getBinary(exp) local v1 = self:getExp(exp[1]) local v2 = self:getExp(exp[2]) - v1 = self:getFirstInMulti(v1) - v2 = self:getFirstInMulti(v2) + v1 = self:getFirstInMulti(v1) or createValue('nil', exp[1]) + v2 = self:getFirstInMulti(v2) or createValue('nil', exp[2]) local op = exp.op -- TODO 搜索元方法 if op == 'or' then @@ -690,9 +691,7 @@ function mt:doReturn(action) end local values = self:unpackList(action) local func = self:getCurrentFunction() - local n = 0 - values:eachValue(function (value) - n = n + 1 + values:eachValue(function (n, value) func:setReturn(n, value) end) end @@ -1128,7 +1127,7 @@ return function (ast, lsp, uri) end local suc, res = xpcall(compile, log.error, ast, lsp, uri) if not suc then - return nil + return nil, res end return res end |