summaryrefslogtreecommitdiff
path: root/server/src/vm/library.lua
blob: 60f56368351459a52ed8839daf4f599eaaae16c4 (plain)
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
local sourceMgr = require 'vm.source'

local createValue
local createFunction

local CHILD_CACHE = {}
local VALUE_CACHE = {}

local buildLibValue
local buildLibChild

function buildLibValue(lib)
    if VALUE_CACHE[lib] then
        return VALUE_CACHE[lib]
    end
    if not createValue then
        createValue = require 'vm.value'
        createFunction = require 'vm.function'
    end
    local tp = lib.type
    local value
    if     tp == 'table' then
        value = createValue('table', sourceMgr.dummy())
    elseif tp == 'function' then
        value = createValue('function', sourceMgr.dummy())
        local func = createFunction()
        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
        end
    elseif tp == 'string' then
        value = createValue('string', sourceMgr.dummy())
    elseif tp == 'boolean' then
        value = createValue('boolean', sourceMgr.dummy())
    elseif tp == 'number' then
        value = createValue('number', sourceMgr.dummy())
    elseif tp == 'integer' then
        value = createValue('integer', sourceMgr.dummy())
    elseif tp == 'nil' then
        value = createValue('nil', sourceMgr.dummy())
    else
        value = createValue(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

    return value
end

function buildLibChild(lib)
    if not createValue then
        createValue = require 'vm.value'
        createFunction = 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,
}