diff options
-rw-r--r-- | server/libs/bee/filesystem.lni | 4 | ||||
-rw-r--r-- | server/libs/lua53/basic.lni | 9 | ||||
-rw-r--r-- | server/libs/lua53/io.lni | 6 | ||||
-rw-r--r-- | server/src/matcher/vm.lua | 126 |
4 files changed, 101 insertions, 44 deletions
diff --git a/server/libs/bee/filesystem.lni b/server/libs/bee/filesystem.lni index 024787ee..1f09307b 100644 --- a/server/libs/bee/filesystem.lni +++ b/server/libs/bee/filesystem.lni @@ -15,8 +15,8 @@ nick = 'fs' [current_path] [[.args]] name = 'new_path' -type = '*bee::filesystem' +type = 'bee::filesystem' optional = 'self' [[.returns]] -type = '*bee::filesystem' +type = 'bee::filesystem' optional = 'self' diff --git a/server/libs/lua53/basic.lni b/server/libs/lua53/basic.lni index 74383619..ae25c68d 100644 --- a/server/libs/lua53/basic.lni +++ b/server/libs/lua53/basic.lni @@ -179,6 +179,15 @@ type = 'table' [[.returns]] name = 'iterator' type = 'function' +returns = { + 1 = { + name = 'i', + type = 'integer', + }, + 2 = { + name = 'object', + }, +} [[.returns]] name = 't' type = 'table' diff --git a/server/libs/lua53/io.lni b/server/libs/lua53/io.lni index 4bd37315..1ba31fb9 100644 --- a/server/libs/lua53/io.lni +++ b/server/libs/lua53/io.lni @@ -16,7 +16,7 @@ type = 'library' name = 'io' [stdin] -type = '*FILE*' +type = 'FILE*' [close] [[.parent]] @@ -27,8 +27,8 @@ type = 'library' name = 'table' [[.parent]] type = 'object' -name = '*FILE*' +name = 'FILE*' [[.args]] -type = '*FILE*' +type = 'FILE*' name = 'file' optional = 'self' diff --git a/server/src/matcher/vm.lua b/server/src/matcher/vm.lua index 5c4736c9..18e1ddd3 100644 --- a/server/src/matcher/vm.lua +++ b/server/src/matcher/vm.lua @@ -68,9 +68,27 @@ function mt:createTable(source) return tbl end +function mt:coverValue(target, source) + for k in pairs(target) do + target[k] = nil + end + for k, v in pairs(source) do + target[k] = v + end +end + function mt:setValue(var, value) assert(not value or value.type ~= 'list') - var.value = value or self:createNil(var) + if var.value then + if var.value.type == 'nil' then + -- 允许覆盖nil + if value.type ~= 'nil' then + self:coverValue(var.value, value) + end + end + else + var.value = value or self:createNil(var) + end return value end @@ -110,6 +128,7 @@ function mt:createFunction(exp, object) returns = { type = 'list', }, + args = {}, } if not exp then @@ -127,14 +146,17 @@ function mt:createFunction(exp, object) return end if arg.type == 'name' then - self:createLocal(arg[1], arg) + local var = self:createLocal(arg[1], arg) + func.args[#func.args+1] = var elseif arg.type == '...' then - self:createDots(arg) + local dots = self:createDots(arg) + func.args[#func.args+1] = dots stop = true end end) if object then - self:createLocal('self', object) + local var = self:createLocal('self', object) + table.insert(func.args, 1, var) end self:doActions(exp) @@ -166,31 +188,32 @@ function mt:call(func, values) if func.used then return self:getFunctionReturns(func) end - func.used = true - if func.args then - for i, var in ipairs(func.args) do - if var then - if var.type == 'dots' then - local list = { - type = 'list', - } - if values then - for n = i, #values do - list[n-i+1] = values[n] - end - self:setValue(var, list) - else - self:setValue(var, nil) + if not func.args then + return self:getFunctionReturns(func) + end + + for i, var in ipairs(func.args) do + if var then + if var.type == 'dots' then + local list = { + type = 'list', + } + if values then + for n = i, #values do + list[n-i+1] = values[n] end - break + self:setValue(var, list) else - if values then - self:setValue(var, values[i]) - else - self:setValue(var, nil) - end + self:setValue(var, nil) + end + break + else + if values then + self:setValue(var, values[i]) + else + self:setValue(var, nil) end end end @@ -203,9 +226,8 @@ function mt:getCurrentFunction() return self.chunk.func end -function mt:setFunctionReturn(index, value) - local func = self:getCurrentFunction() - func.returns[index] = value +function mt:setFunctionReturn(func, index, value) + func.returns[index] = value or self:createNil() end function mt:getFunctionReturns(func) @@ -257,25 +279,47 @@ function mt:createNil(source) } end -function mt:setLib(obj, lib) - obj.lib = lib +function mt:createCustom(tp, source) + return { + type = tp, + source = source or DefaultSource, + } +end + +function mt:getLibValue(lib) local tp = lib.type if not tp then return end + local value if tp == 'table' then - self:setValue(obj, self:createTable()) + value = self:createTable() elseif tp == 'function' then - self:setValue(obj, self:createFunction()) -- TODO + value = self:createFunction() + if lib.returns then + for i, rtn in ipairs(lib.returns) do + self:setFunctionReturn(value, i, self:getLibValue(rtn)) + end + end + if lib.args then + local values = {} + for i, arg in ipairs(lib.args) do + values[i] = self:getLibValue(arg) or self:createNil() + end + self:call(value, values) + end elseif tp == 'string' then - self:setValue(obj, self:createString(lib.value)) + value = self:createString(lib.value) elseif tp == 'boolean' then - self:setValue(obj, self:createBoolean(lib.value)) + value = self:createBoolean(lib.value) elseif tp == 'number' then - self:setValue(obj, self:createNumber(lib.value)) + value = self:createNumber(lib.value) elseif tp == 'integer' then - self:setValue(obj, self:createInteger(lib.value)) + value = self:createInteger(lib.value) + else + value = self:createCustom(tp) end + return value end function mt:getName(name, source) @@ -473,7 +517,7 @@ end function mt:doReturn(action) for i, exp in ipairs(action) do local value = self:getExp(exp) - self:setFunctionReturn(i, value) + self:setFunctionReturn(self:getCurrentFunction(), i, value) end end @@ -663,13 +707,17 @@ function mt:createEnvironment() for name, info in pairs(library.global) do local field = self:createField(pValue, name) if info.lib then - self:setLib(field, info.lib) + local value = self:getLibValue(info.lib) + self:setValue(field, value) + value.lib = info.lib end if info.child then local fValue = self:getValue(field) for fname, flib in pairs(info.child) do local ffield = self:createField(fValue, fname) - self:setLib(ffield, flib) + local value = self:getLibValue(flib) + self:setValue(ffield, value) + value.lib = flib end end end |