diff options
Diffstat (limited to 'server/src')
-rw-r--r-- | server/src/emmy/manager.lua | 10 | ||||
-rw-r--r-- | server/src/emmy/param.lua | 31 | ||||
-rw-r--r-- | server/src/parser/ast.lua | 2 | ||||
-rw-r--r-- | server/src/vm/emmy.lua | 27 | ||||
-rw-r--r-- | server/src/vm/function.lua | 26 | ||||
-rw-r--r-- | server/src/vm/value.lua | 7 | ||||
-rw-r--r-- | server/src/vm/vm.lua | 1 |
7 files changed, 102 insertions, 2 deletions
diff --git a/server/src/emmy/manager.lua b/server/src/emmy/manager.lua index fe14173c..d8b3b656 100644 --- a/server/src/emmy/manager.lua +++ b/server/src/emmy/manager.lua @@ -3,6 +3,7 @@ local newClass = require 'emmy.class' local newType = require 'emmy.type' local newTypeUnit = require 'emmy.typeUnit' local newAlias = require 'emmy.alias' +local newParam = require 'emmy.param' local mt = {} mt.__index = mt @@ -104,6 +105,15 @@ function mt:addAlias(source, typeObj) return aliasObj end +function mt:addParam(source, typeObj) + local paramName = source[1][1] + local paramObj = newParam(self, source) + paramObj:bindType(typeObj) + local list = self:getClass(paramName) + list[source.id] = paramObj + return paramObj +end + function mt:remove() end diff --git a/server/src/emmy/param.lua b/server/src/emmy/param.lua new file mode 100644 index 00000000..9c18bfec --- /dev/null +++ b/server/src/emmy/param.lua @@ -0,0 +1,31 @@ +local listMgr = require 'vm.list' + +---@class EmmyParam +local mt = {} +mt.__index = mt +mt.type = 'emmy.param' + +function mt:getName() + return self.name +end + +function mt:getSource() + return listMgr.get(self.source) +end + +function mt:bindType(type) + if type then + self._bindType = type + else + return self._bindType + end +end + +return function (manager, source) + local self = setmetatable({ + name = source[1][1], + source = source.id, + _manager = manager, + }, mt) + return self +end diff --git a/server/src/parser/ast.lua b/server/src/parser/ast.lua index 8c703491..7df7676d 100644 --- a/server/src/parser/ast.lua +++ b/server/src/parser/ast.lua @@ -629,7 +629,7 @@ local Defs = { end if isField then table[#table+1] = arg - if arg.finish then + if arg.type:sub(1, 4) ~= 'emmy' then wantField = false start = arg.finish + 1 end diff --git a/server/src/vm/emmy.lua b/server/src/vm/emmy.lua index a2a38553..5406aab1 100644 --- a/server/src/vm/emmy.lua +++ b/server/src/vm/emmy.lua @@ -2,6 +2,7 @@ local mt = require 'vm.manager' function mt:clearEmmy() self._emmy = nil + self._emmyParams = nil end function mt:doEmmy(action) @@ -13,6 +14,7 @@ function mt:doEmmy(action) elseif tp == 'emmyAlias' then self:doEmmyAlias(action) elseif tp == 'emmyParam' then + self:doEmmyParam(action) elseif tp == 'emmyReturn' then elseif tp == 'emmyField' then elseif tp == 'emmyGeneric' then @@ -33,6 +35,19 @@ function mt:getEmmy() return emmy end +function mt:addEmmyParam(param) + if not self._emmyParams then + self._emmyParams = {} + end + self._emmyParams[#self._emmyParams+1] = param +end + +function mt:getEmmyParams() + local params = self._emmyParams + self._emmyParams = nil + return params +end + function mt:doEmmyClass(action) ---@type emmyMgr local emmyMgr = self.emmyMgr @@ -83,6 +98,18 @@ function mt:doEmmyAlias(action) end end +function mt:doEmmyParam(action) + ---@type emmyMgr + local emmyMgr = self.emmyMgr + self:instantSource(action) + self:instantSource(action[1]) + local type = self:doEmmyType(action[2]) + local param = emmyMgr:addParam(action, type) + action:set('emmy.param', param) + self._emmy = nil + self:addEmmyParam(param) +end + function mt:doEmmyIncomplete(action) self:instantSource(action) end diff --git a/server/src/vm/function.lua b/server/src/vm/function.lua index 7df9c3ea..dff5952d 100644 --- a/server/src/vm/function.lua +++ b/server/src/vm/function.lua @@ -275,13 +275,33 @@ function mt:setArgs(values) end end +function mt:findEmmyParamByName(name) + local params = self._emmyParams + if not params then + return nil + end + for i = #params, 1, -1 do + local param = params[i] + if param:getName() == name then + return param + end + end + return nil +end + function mt:createArg(vm, arg) vm:instantSource(arg) arg:set('arg', true) if arg.type == 'name' then - local loc = localMgr.create(arg[1], arg, valueMgr.create('nil', arg)) + local emmyParam = self:findEmmyParamByName(arg[1]) + local value = valueMgr.create('nil', arg) + if emmyParam then + value:setEmmy(emmyParam:bindType()) + end + local loc = localMgr.create(arg[1], arg, value) self:saveUpvalue(arg[1], loc) self.args[#self.args+1] = loc + elseif arg.type == '...' then self._dots = createMulti() end @@ -360,6 +380,10 @@ function mt:markGlobal() end end +function mt:setEmmyParams(params) + self._emmyParams = params +end + local function create(source) if not source then error('Function need source') diff --git a/server/src/vm/value.lua b/server/src/vm/value.lua index 8a0b0861..9f9b6b7c 100644 --- a/server/src/vm/value.lua +++ b/server/src/vm/value.lua @@ -289,6 +289,13 @@ function mt:mergeType(value) if not value then return end + if self._emmy and not value._emmy then + value._emmy = self._emmy + return + elseif not self._emmy and value._emmy then + self._emmy = value._emmy + return + end if value._type then for tp, rate in pairs(value._type) do self:setType(tp, rate) diff --git a/server/src/vm/vm.lua b/server/src/vm/vm.lua index a6d5f9ea..b37ff153 100644 --- a/server/src/vm/vm.lua +++ b/server/src/vm/vm.lua @@ -1063,6 +1063,7 @@ end function mt:createFunction(source) local value = self:createValue('function', source) local func = functionMgr.create(source) + func:setEmmyParams(self:getEmmyParams()) value:setFunction(func) value:setType('function', 1.0) if source:getUri() == self.uri then |