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
|
local mt = require 'vm.manager'
local multi = require 'vm.multi'
local library = require 'core.library'
local libraryBuilder = require 'vm.library'
local plugin = require 'plugin'
---@param func emmyFunction
---@param values table
function mt:callEmmySpecial(func, values, source)
local emmyParams = func:getEmmyParams()
for index, param in ipairs(emmyParams) do
local option = param:getOption()
if option and type(option.special) == 'string' then
self:checkEmmyParam(func, values, index, option.special, source)
end
end
end
---@param func emmyFunction
---@param values table
---@param index integer
---@param special string
function mt:checkEmmyParam(func, values, index, special, source)
if special == 'dofile:1' then
self:callEmmyDoFile(func, values, index)
elseif special == 'loadfile:1' then
self:callEmmyLoadFile(func, values, index)
elseif special == 'pcall:1' then
self:callEmmyPCall(func, values, index, source)
elseif special == 'require:1' then
self:callEmmyRequire(func, values, index)
end
end
---@param func emmyFunction
---@param values table
---@param index integer
function mt:callEmmyDoFile(func, values, index)
if not values[index] then
values[index] = self:createValue('any', self:getDefaultSource())
end
local str = values[index]:getLiteral()
if type(str) ~= 'string' then
return
end
local requireValue = self:tryRequireOne(str, values[index], 'dofile')
if not requireValue then
requireValue = self:createValue('any', self:getDefaultSource())
requireValue.isRequire = true
end
func:setReturn(1, requireValue)
end
---@param func emmyFunction
---@param values table
---@param index integer
function mt:callEmmyLoadFile(func, values, index)
if not values[index] then
values[index] = self:createValue('any', self:getDefaultSource())
end
local str = values[index]:getLiteral()
if type(str) ~= 'string' then
return
end
local requireValue = self:tryRequireOne(str, values[index], 'loadfile')
if not requireValue then
requireValue = self:createValue('any', self:getDefaultSource())
requireValue:set('cross file', true)
end
func:setReturn(1, requireValue)
end
---@param func emmyFunction
---@param values table
---@param index integer
---@param source source
function mt:callEmmyPCall(func, values, index, source)
local funcValue = values[index]
if not funcValue then
return
end
local realFunc = funcValue:getFunction()
if not realFunc then
return
end
local argList = multi()
values:eachValue(function (i, v)
if i > index then
argList:push(v)
end
end)
self:call(funcValue, argList, source)
if realFunc ~= func then
func:setReturn(1, self:createValue('boolean', source))
realFunc:getReturn():eachValue(function (i, v)
func:setReturn(i + 1, v)
end)
end
end
---@param func emmyFunction
---@param values table
---@param index integer
function mt:callEmmyRequire(func, values, index)
if not values[index] then
values[index] = self:createValue('any', self:getDefaultSource())
end
local strValue = values[index]
local strSource = strValue:getSource()
if not strSource then
return nil
end
local str = strValue:getLiteral()
local raw = self.text:sub(strSource.start, strSource.finish)
str = plugin.call('OnRequirePath', str, raw) or str
local lib = library.library[str]
if lib then
local value = libraryBuilder.value(lib)
value:markGlobal()
func:setReturn(1, value)
return
else
local requireValue = self:tryRequireOne(str, strValue, 'require')
if not requireValue then
requireValue = self:createValue('any', self:getDefaultSource())
requireValue:set('cross file', true)
end
func:setReturn(1, requireValue)
end
end
|