summaryrefslogtreecommitdiff
path: root/server/src/vm/source.lua
blob: 59d5d66dd13ccbe75b7ee34618185bbe60fed321 (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
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
local listMgr = require 'vm.list'

local mt = {}
mt.__index = mt
mt.type = 'source'
mt.uri = ''
mt.start = 0
mt.finish = 0
mt.id = 0

local Watch = setmetatable({}, {__mode = 'k'})

function mt:bindLocal(loc, action)
    if loc then
        self._bindLocal = loc
        self._bindValue = loc:getValue()
        self._action = action
        loc:addInfo(action, self)
    else
        if not self._bindLocal then
            return nil
        end
        if not self._bindLocal:getSource() then
            self._bindLocal = nil
            return nil
        end
        return self._bindLocal
    end
end

function mt:bindLabel(label, action)
    if label then
        self._bindLabel = label
        self._action = action
        label:addInfo(action, self)
    else
        return self._bindLabel
    end
end

function mt:bindFunction(func)
    if func then
        self._bindFunction = func
    else
        return self._bindFunction
    end
end

function mt:bindValue(value, action)
    if value then
        self._bindValue = value
        self._action = action
        value:addInfo(action, self)
    else
        return self._bindValue
    end
end

function mt:bindCall(args)
    if args then
        self._bindCallArgs = args
    else
        return self._bindCallArgs
    end
end

function mt:action()
    return self._action
end

function mt:setUri(uri)
    self.uri = uri
end

function mt:getUri()
    return self.uri
end

function mt:set(name, v)
    if not self._flag then
        self._flag = {}
    end
    self._flag[name] = v
end

function mt:get(name)
    if not self._flag then
        return nil
    end
    return self._flag[name]
end

function mt:getName()
    return self[1]
end

function mt:kill()
    self._dead = true
    listMgr.clear(self.id)
end

function mt:isDead()
    return self._dead
end

function mt:findValue()
    local value = self:bindValue()
    if not value then
        return nil
    end
    if not value:isGlobal() then
        return value
    end
    if self.type ~= 'name' then
        return value
    end
    local parent = self:get 'parent'
    if not parent then
        return value
    end
    local name = self[1]
    if type(name) ~= 'string' then
        return value
    end
    return parent:getChild(name) or value
end

function mt:findCallFunction()
    local simple = self:get 'simple'
    if not simple then
        return nil
    end
    local source
    for i = 1, #simple do
        if simple[i] == self then
            source = simple[i-1]
        end
    end
    if not source then
        return nil
    end
    local value = source:bindValue()
    if value and value:getFunction() then
        return value
    end
    value = source:findValue()
    if value and value:getFunction() then
        return value
    end
    return nil
end

local function instant(source)
    if source.id then
        return false
    end
    local id = listMgr.add(source)
    source.id = id
    Watch[source] = id
    setmetatable(source, mt)
    return true
end

local function dummy()
    local src = {}
    instant(src)
    return src
end

return {
    instant = instant,
    watch = Watch,
    dummy = dummy,
}