Skip to content

Commit 0ab880e

Browse files
committed
stash
1 parent eb05f7a commit 0ab880e

File tree

1 file changed

+74
-59
lines changed

1 file changed

+74
-59
lines changed

script/vm/tracer.lua

Lines changed: 74 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---@class vm
22
local vm = require 'vm.vm'
33
local guide = require 'parser.guide'
4+
local util = require 'utility'
45

56
---@class parser.object
67
---@field package _tracer? vm.tracer
@@ -102,106 +103,120 @@ function mt:getLastAssign(block, pos)
102103
return assign
103104
end
104105

105-
---@param filter parser.object
106-
---@param node vm.node?
107-
---@return vm.node
108-
function mt:narrowByFilter(filter, node)
106+
---@param source parser.object
107+
---@return vm.node?
108+
function mt:narrow(source)
109+
local node = self:getNode(source)
109110
if not node then
110-
node = vm.createNode()
111-
end
112-
if filter.type == 'filter' then
113-
node = self:narrowByFilter(filter.exp, node)
114-
return node
111+
return nil
115112
end
116-
if filter.type == 'getlocal' then
117-
if filter.node == self.source then
118-
node = node:copy()
119-
node:removeOptional()
120-
end
113+
114+
if source.type == 'getlocal' then
115+
node = node:copy():setTruthy()
121116
return node
122117
end
123-
return node
118+
119+
return nil
124120
end
125121

126122
---@param source parser.object
127123
---@return vm.node?
128124
function mt:calcNode(source)
129125
if source.type == 'getlocal' then
130-
return nil
131-
end
132-
if source.type == 'local' then
133-
if source ~= self.source then
126+
if source.node ~= self.source then
134127
return nil
135128
end
129+
local block = guide.getParentBlock(source)
130+
if not block then
131+
return nil
132+
end
133+
local lastAssign = self:getLastAssign(block, source.start)
134+
if lastAssign then
135+
local node = self:getNode(lastAssign)
136+
return node
137+
end
138+
local parent = source.parent
139+
while true do
140+
if parent.type == 'filter'
141+
or parent.type == 'unary'
142+
or parent.type == 'ifblock'
143+
or parent.type == 'elseifblock' then
144+
parent = parent.parent
145+
else
146+
break
147+
end
148+
end
149+
local node = self:getNode(parent)
150+
return node
136151
end
137152
if source.type == 'setlocal' then
138153
if source.node ~= self.source then
139154
return nil
140155
end
156+
local node = vm.compileNode(source)
157+
return node
141158
end
142-
if guide.isSet(source) then
159+
if source.type == 'local'
160+
or source.type == 'self' then
161+
if source ~= self.source then
162+
return nil
163+
end
143164
local node = vm.compileNode(source)
144165
return node
145166
end
167+
if source.type == 'filter' then
168+
local node = self:narrow(source.exp)
169+
return node
170+
end
146171
if source.type == 'do' then
147172
local lastAssign = self:getLastAssign(source, source.finish)
148-
return self:getNode(lastAssign or source.parent)
173+
local node = self:getNode(lastAssign or source.parent)
174+
return node
149175
end
150176
if source.type == 'ifblock' then
151-
local currentNode = self:getNode(source.parent)
152-
local narrowedNode = self:narrowByFilter(source.filter, currentNode)
153-
return narrowedNode
177+
local filter = source.filter
178+
if filter then
179+
local node = self:getNode(filter)
180+
return node
181+
end
154182
end
155-
if source.type == 'filter' then
156-
local parent = source.parent
157-
---@type parser.object
158-
local outBlock
159-
if parent.type == 'ifblock' then
160-
outBlock = parent.parent.parent
161-
local lastAssign = self:getLastAssign(outBlock, parent.start)
162-
return self:getNode(lastAssign or source.parent)
163-
elseif parent.type == 'elseifblock' then
164-
outBlock = parent.parent.parent
165-
local lastAssign = self:getLastAssign(outBlock, parent.start)
166-
return self:getNode(lastAssign or source.parent)
167-
elseif parent.type == 'while' then
168-
outBlock = parent.parent
169-
local lastAssign = self:getLastAssign(outBlock, parent.start)
170-
return self:getNode(lastAssign or source.parent)
171-
elseif parent.type == 'repeat' then
172-
outBlock = parent.parent
173-
local lastAssign = self:getLastAssign(outBlock, parent.start)
174-
return self:getNode(lastAssign or source.parent)
175-
end
176-
assert(outBlock, parent.type)
183+
if source.type == 'unary' then
184+
if source.op.type == 'not' then
185+
local node = self:getNode(source[1])
186+
if node then
187+
node = node:copy()
188+
node:setFalsy()
189+
return node
190+
end
191+
end
177192
end
178-
return nil
193+
194+
local block = guide.getParentBlock(source)
195+
if not block then
196+
return nil
197+
end
198+
local lastAssign = self:getLastAssign(block, source.start)
199+
local node = self:getNode(lastAssign or source.parent)
200+
return node
179201
end
180202

181203
---@param source parser.object
182204
---@return vm.node?
183205
function mt:getNode(source)
184-
if self.nodes[source] ~= nil then
185-
return self.nodes[source] or nil
186-
end
187-
local parentBlock = guide.getParentBlock(source)
188-
if not parentBlock then
189-
self.nodes[source] = false
190-
return nil
206+
local cache = self.nodes[source]
207+
if cache ~= nil then
208+
return cache or nil
191209
end
192210
if source == self.main then
193211
self.nodes[source] = false
194212
return nil
195213
end
214+
self.nodes[source] = false
196215
local node = self:calcNode(source)
197216
if node then
198217
self.nodes[source] = node
199-
return node
200218
end
201-
local lastAssign = self:getLastAssign(parentBlock, source.start)
202-
local parentNode = self:getNode(lastAssign or source.parent)
203-
self.nodes[source] = parentNode or false
204-
return parentNode
219+
return node
205220
end
206221

207222
---@param source parser.object

0 commit comments

Comments
 (0)