1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
local linker = require "core.linker"
---@class generic.value
---@field type string
---@field closure generic.closure
---@field proto parser.guide.object
---@field parent parser.guide.object
---@class generic.closure
---@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,
}
return value
end
---递归实例化对象
---@param obj parser.guide.object
---@return generic.value
local function createValue(closure, obj, callback, road)
if callback then
road = road or {}
end
if obj.type == 'doc.type' then
local types = {}
local hasGeneric
for i, tp in ipairs(obj.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, obj)
value.types = types
linker.compileLink(value)
return value
end
if obj.type == 'doc.type.name' then
if not obj.typeGeneric then
return nil
end
local key = obj[1]
local value = instantValue(closure, obj)
if callback then
callback(road, key, obj)
end
linker.compileLink(value)
return value
end
end
-- 为所有的 param 与 return 创建副本
---@param closure generic.closure
local function buildValues(closure)
local protoFunction = closure.proto
local upvalues = closure.upvalues
local params = closure.call.args
if protoFunction.type == 'function' then
for _, doc in ipairs(protoFunction.bindDocs) do
if doc.type == 'doc.param' then
local extends = doc.extends
local index = extends.paramIndex
closure.params[index] = createValue(closure, extends, function (road, key, proto)
local param = params[index]
if not param then
return
end
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 = linker.getID(param)
end
if not paramID then
return
end
if not upvalues[key] then
upvalues[key] = {}
end
-- TODO
upvalues[key][#upvalues[key]+1] = paramID
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)
end
end
end
end
if protoFunction.type == 'doc.function' then
end
end
---创建一个闭包
---@param protoFunction parser.guide.object # 原型函数
---@param parentClosure? generic.closure
---@return generic.closure
function m.createClosure(protoFunction, call, parentClosure)
---@type generic.closure
local closure = {
type = 'generic.closure',
parent = protoFunction.parent,
proto = protoFunction,
call = call,
upvalues = parentClosure and parentClosure.upvalues or {},
params = {},
returns = {},
}
buildValues(closure)
if #closure.returns == 0 then
return nil
end
linker.compileLink(closure)
return closure
end
return m
|