summaryrefslogtreecommitdiff
path: root/script/core/generic.lua
diff options
context:
space:
mode:
Diffstat (limited to 'script/core/generic.lua')
-rw-r--r--script/core/generic.lua282
1 files changed, 0 insertions, 282 deletions
diff --git a/script/core/generic.lua b/script/core/generic.lua
deleted file mode 100644
index 2eb454ff..00000000
--- a/script/core/generic.lua
+++ /dev/null
@@ -1,282 +0,0 @@
-local guide = require 'parser.guide'
-local noder = require "core.noder"
-
----@class generic.value: parser.guide.object
----@field type string
----@field closure generic.closure
----@field proto parser.guide.object
----@field parent parser.guide.object
-
----@class generic.closure: parser.guide.object
----@field type string
----@field proto parser.guide.object
----@field upvalues table<string, generic.value[]>
----@field params generic.value[]
----@field returns generic.value[]
-
-local m = {}
-
----@param closure generic.closure
----@param proto parser.guide.object
-local function instantValue(closure, proto)
- ---@type generic.value
- local value = {
- type = 'generic.value',
- closure = closure,
- proto = proto,
- parent = proto.parent,
- }
- closure.values[#closure.values+1] = value
- return value
-end
-
----递归实例化对象
----@param proto parser.guide.object
----@return generic.value
-local function createValue(closure, proto, callback, road)
- road = road or {}
- if proto.type == 'doc.type' then
- local types = {}
- local hasGeneric
- for i, tp in ipairs(proto.types) do
- local genericValue = createValue(closure, tp, callback, road)
- if genericValue then
- hasGeneric = true
- types[i] = genericValue
- else
- types[i] = tp
- end
- end
- if not hasGeneric then
- return nil
- end
- local value = instantValue(closure, proto)
- value.types = types
- noder.compileNode(noder.getNoders(proto), value)
- return value
- end
- if proto.type == 'doc.type.name' then
- if not proto.typeGeneric then
- return nil
- end
- local key = proto[1]
- local value = instantValue(closure, proto)
- if callback then
- callback(road, key, proto)
- end
- noder.compileNode(noder.getNoders(proto), value)
- return value
- end
- if proto.type == 'doc.type.function' then
- local hasGeneric
- local args = {}
- local returns = {}
- for i, arg in ipairs(proto.args) do
- local value = createValue(closure, arg, callback, road)
- if value then
- hasGeneric = true
- end
- args[i] = value or arg
- end
- for i, rtn in ipairs(proto.returns) do
- local value = createValue(closure, rtn, callback, road)
- if value then
- hasGeneric = true
- end
- returns[i] = value or rtn
- end
- if not hasGeneric then
- return nil
- end
- local value = instantValue(closure, proto)
- value.args = args
- value.returns = returns
- value.isGeneric = true
- noder.pushSource(noder.getNoders(proto), value)
- return value
- end
- if proto.type == 'doc.type.array' then
- road[#road+1] = noder.WEAK_ANY_FIELD
- local node = createValue(closure, proto.node, callback, road)
- road[#road] = nil
- if not node then
- return nil
- end
- local value = instantValue(closure, proto)
- value.node = node
- noder.compileNode(noder.getNoders(proto), value)
- return value
- end
- if proto.type == 'doc.type.table' then
- road[#road+1] = noder.WEAK_TABLE_KEY
- local tkey = createValue(closure, proto.tkey, callback, road)
- road[#road] = nil
-
- road[#road+1] = noder.WEAK_ANY_FIELD
- local tvalue = createValue(closure, proto.tvalue, callback, road)
- road[#road] = nil
-
- if not tkey and not tvalue then
- return nil
- end
- local value = instantValue(closure, proto)
- value.tkey = tkey or proto.tkey
- value.tvalue = tvalue or proto.tvalue
- noder.compileNode(noder.getNoders(proto), value)
- return value
- end
- if proto.type == 'doc.type.ltable' then
- local fields = {}
- for i, field in ipairs(proto.fields) do
- fields[i] = createValue(closure, field, callback, road) or field
- end
- if #fields == 0 then
- return nil
- end
- local value = instantValue(closure, proto)
- value.fields = fields
- noder.compileNode(noder.getNoders(proto), value)
- return value
- end
- if proto.type == 'doc.type.field' then
- local name = proto.name[1]
- if type(name) == 'string' then
- road[#road+1] = ('%s%s'):format(
- noder.STRING_FIELD,
- name
- )
- else
- road[#road+1] = ('%s%s'):format(
- noder.SPLIT_CHAR,
- name
- )
- end
- local typeUnit = createValue(closure, proto.extends, callback, road)
- road[#road] = nil
- if not typeUnit then
- return nil
- end
- local value = instantValue(closure, proto)
- value.name = proto.name
- value.extends = typeUnit
- noder.compileNode(noder.getNoders(proto), value)
- return value
- end
-end
-
-local function buildValue(road, key, proto, param, upvalues)
- local paramID
- if proto.literal then
- local str = param.type == 'string' and param[1]
- if not str then
- return
- end
- paramID = 'dn:' .. str
- else
- paramID = noder.getID(param)
- end
- if not paramID then
- return
- end
- local myUri = guide.getUri(param)
- local myHead = noder.URI_CHAR .. myUri .. noder.URI_CHAR
- paramID = myHead .. paramID
- if not upvalues[key] then
- upvalues[key] = {}
- end
- upvalues[key][#upvalues[key]+1] = paramID .. table.concat(road)
-end
-
--- 为所有的 param 与 return 创建副本
----@param closure generic.closure
-local function buildValues(closure)
- local protoFunction = closure.proto
- local upvalues = closure.upvalues
- local params = closure.call.args
- local args = protoFunction.args
- local paramMap = {}
- if params then
- for i, param in ipairs(params) do
- local arg = args and args[i]
- if arg then
- if arg.type == 'local' then
- paramMap[arg[1]] = param
- elseif arg.type == 'doc.type.arg' then
- paramMap[arg.name[1]] = param
- end
- end
- end
- end
-
- if protoFunction.type == 'function' then
- for _, doc in ipairs(protoFunction.bindDocs) do
- if doc.type == 'doc.param' then
- local name = doc.param[1]
- local extends = doc.extends
- if name and extends then
- local param = paramMap[name]
- closure.params[name] = param and createValue(closure, extends, function (road, key, proto)
- buildValue(road, key, proto, param, upvalues)
- end) or extends
- end
- end
- end
- for _, doc in ipairs(protoFunction.bindDocs) do
- if doc.type == 'doc.return' then
- for _, rtn in ipairs(doc.returns) do
- closure.returns[rtn.returnIndex] = createValue(closure, rtn) or rtn
- end
- end
- end
- end
- if protoFunction.type == 'doc.type.function' then
- for index, arg in ipairs(protoFunction.args) do
- local name = arg.name[1]
- local extends = arg.extends
- local param = paramMap[name]
- closure.params[name] = param and createValue(closure, extends, function (road, key, proto)
- buildValue(road, key, proto, param, upvalues)
- end) or extends
- end
- for index, rtn in ipairs(protoFunction.returns) do
- closure.returns[index] = createValue(closure, rtn) or rtn
- end
- end
-end
-
----创建一个闭包
----@param proto parser.guide.object|generic.value # 原型函数|泛型值
----@return generic.closure
-function m.createClosure(proto, call)
- local protoFunction, parentClosure
- if proto.type == 'function' then
- protoFunction = proto
- elseif proto.type == 'doc.type.function' then
- protoFunction = proto
- elseif proto.type == 'generic.value' then
- protoFunction = proto.proto
- parentClosure = proto.closure
- end
- ---@type generic.closure
- local closure = {
- type = 'generic.closure',
- parent = protoFunction.parent,
- proto = protoFunction,
- call = call,
- upvalues = parentClosure and parentClosure.upvalues or {},
- params = {},
- returns = {},
- values = {},
- }
- buildValues(closure)
-
- if #closure.returns == 0 then
- return nil
- end
-
- noder.compileNode(noder.getNoders(proto), closure)
-
- return closure
-end
-
-return m