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
|
local sourceMgr = require 'vm.source'
local valueMgr
local functionMgr
local CHILD_CACHE = {}
local VALUE_CACHE = {}
local Special = {}
local buildLibValue
local buildLibChild
function buildLibValue(lib)
if VALUE_CACHE[lib] then
return VALUE_CACHE[lib]
end
if not valueMgr then
valueMgr = require 'vm.value'
functionMgr = require 'vm.function'
end
local tp = lib.type
local value
if tp == 'table' then
value = valueMgr.create('table', sourceMgr.dummy())
elseif tp == 'function' then
local dummySource = sourceMgr.dummy()
value = valueMgr.create('function', dummySource)
local func = functionMgr.create(dummySource)
value:setFunction(func)
if lib.args then
for _, arg in ipairs(lib.args) do
func:createLibArg(arg, sourceMgr.dummy())
end
end
if lib.returns then
for i, rtn in ipairs(lib.returns) do
if rtn.type == '...' then
func:returnDots(i)
else
func:setReturn(i, buildLibValue(rtn))
end
end
if lib.special == 'pairs' then
func:setReturn(1, Special['next'])
end
if lib.special == 'ipairs' then
func:setReturn(1, Special['@ipairs'])
end
end
elseif tp == 'string' then
value = valueMgr.create('string', sourceMgr.dummy())
elseif tp == 'boolean' then
value = valueMgr.create('boolean', sourceMgr.dummy())
elseif tp == 'number' then
value = valueMgr.create('number', sourceMgr.dummy())
elseif tp == 'integer' then
value = valueMgr.create('integer', sourceMgr.dummy())
elseif tp == 'nil' then
value = valueMgr.create('nil', sourceMgr.dummy())
else
value = valueMgr.create(tp or 'any', sourceMgr.dummy())
end
value:setLib(lib)
VALUE_CACHE[lib] = value
if lib.child then
for fName, fLib in pairs(lib.child) do
local fValue = buildLibValue(fLib)
value:rawSet(fName, fValue)
value:addInfo('set child', sourceMgr.dummy(), fName, fValue)
end
end
if lib.special == 'next' then
Special['next'] = value
end
if lib.special == '@ipairs' then
Special['@ipairs'] = value
return nil
end
return value
end
function buildLibChild(lib)
if not valueMgr then
valueMgr = require 'vm.value'
functionMgr = require 'vm.function'
end
if CHILD_CACHE[lib] then
return CHILD_CACHE[lib]
end
local child = {}
for fName, fLib in pairs(lib.child) do
local fValue = buildLibValue(fLib)
child[fName] = fValue
end
CHILD_CACHE[lib] = child
return child
end
local function clearCache()
CHILD_CACHE = {}
VALUE_CACHE = {}
end
return {
value = buildLibValue,
child = buildLibChild,
clear = clearCache,
special = Special,
}
|