Skip to content

Commit eb05f7a

Browse files
committed
stash
1 parent ed97a9e commit eb05f7a

File tree

4 files changed

+105
-23
lines changed

4 files changed

+105
-23
lines changed

script/parser/compile.lua

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3136,6 +3136,22 @@ local function parseGoTo()
31363136
return action
31373137
end
31383138

3139+
local function parseFilter()
3140+
local exp = parseExp()
3141+
if exp then
3142+
local filter = {
3143+
type = 'filter',
3144+
start = exp.start,
3145+
finish = exp.finish,
3146+
exp = exp,
3147+
}
3148+
exp.parent = filter
3149+
return filter
3150+
else
3151+
missExp()
3152+
end
3153+
end
3154+
31393155
local function parseIfBlock(parent)
31403156
local ifLeft = getPosition(Tokens[Index], 'left')
31413157
local ifRight = getPosition(Tokens[Index] + 1, 'right')
@@ -3151,13 +3167,11 @@ local function parseIfBlock(parent)
31513167
}
31523168
}
31533169
skipSpace()
3154-
local filter = parseExp()
3170+
local filter = parseFilter()
31553171
if filter then
31563172
ifblock.filter = filter
31573173
ifblock.finish = filter.finish
31583174
filter.parent = ifblock
3159-
else
3160-
missExp()
31613175
end
31623176
skipSpace()
31633177
local thenToken = Tokens[Index + 1]
@@ -3210,13 +3224,11 @@ local function parseElseIfBlock(parent)
32103224
}
32113225
Index = Index + 2
32123226
skipSpace()
3213-
local filter = parseExp()
3227+
local filter = parseFilter()
32143228
if filter then
32153229
elseifblock.filter = filter
32163230
elseifblock.finish = filter.finish
32173231
filter.parent = elseifblock
3218-
else
3219-
missExp()
32203232
end
32213233
skipSpace()
32223234
local thenToken = Tokens[Index + 1]
@@ -3524,15 +3536,16 @@ local function parseWhile()
35243536

35253537
skipSpace()
35263538
local nextToken = Tokens[Index + 1]
3527-
local filter = nextToken ~= 'do'
3528-
and nextToken ~= 'then'
3529-
and parseExp()
3530-
if filter then
3531-
action.filter = filter
3532-
action.finish = filter.finish
3533-
filter.parent = action
3534-
else
3539+
if nextToken == 'do'
3540+
or nextToken == 'then' then
35353541
missExp()
3542+
else
3543+
local filter = parseFilter()
3544+
if filter then
3545+
action.filter = filter
3546+
action.finish = filter.finish
3547+
filter.parent = action
3548+
end
35363549
end
35373550

35383551
skipSpace()
@@ -3611,12 +3624,10 @@ local function parseRepeat()
36113624
Index = Index + 2
36123625

36133626
skipSpace()
3614-
local filter = parseExp()
3627+
local filter = parseFilter()
36153628
if filter then
36163629
action.filter = filter
36173630
filter.parent = action
3618-
else
3619-
missExp()
36203631
end
36213632

36223633
else

script/parser/guide.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ local childMap = {
139139
['getfield'] = {'node', 'field'},
140140
['list'] = {'#'},
141141
['binary'] = {1, 2},
142-
['unary'] = {1},
142+
['unary'] = { 1 },
143+
['filter'] = {'exp'},
143144

144145
['doc'] = {'#'},
145146
['doc.class'] = {'class', '#extends', '#signs', 'comment'},

script/vm/tracer.lua

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,21 +102,80 @@ function mt:getLastAssign(block, pos)
102102
return assign
103103
end
104104

105+
---@param filter parser.object
106+
---@param node vm.node?
107+
---@return vm.node
108+
function mt:narrowByFilter(filter, node)
109+
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
115+
end
116+
if filter.type == 'getlocal' then
117+
if filter.node == self.source then
118+
node = node:copy()
119+
node:removeOptional()
120+
end
121+
return node
122+
end
123+
return node
124+
end
125+
105126
---@param source parser.object
106127
---@return vm.node?
107128
function mt:calcNode(source)
129+
if source.type == 'getlocal' then
130+
return nil
131+
end
132+
if source.type == 'local' then
133+
if source ~= self.source then
134+
return nil
135+
end
136+
end
137+
if source.type == 'setlocal' then
138+
if source.node ~= self.source then
139+
return nil
140+
end
141+
end
108142
if guide.isSet(source) then
109143
local node = vm.compileNode(source)
110144
return node
111145
end
112146
if source.type == 'do' then
113147
local lastAssign = self:getLastAssign(source, source.finish)
114-
if lastAssign then
115-
return self:getNode(lastAssign)
116-
else
117-
return nil
148+
return self:getNode(lastAssign or source.parent)
149+
end
150+
if source.type == 'ifblock' then
151+
local currentNode = self:getNode(source.parent)
152+
local narrowedNode = self:narrowByFilter(source.filter, currentNode)
153+
return narrowedNode
154+
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)
118175
end
176+
assert(outBlock, parent.type)
119177
end
178+
return nil
120179
end
121180

122181
---@param source parser.object
@@ -140,7 +199,7 @@ function mt:getNode(source)
140199
return node
141200
end
142201
local lastAssign = self:getLastAssign(parentBlock, source.start)
143-
local parentNode = self:getNode(lastAssign or parentBlock)
202+
local parentNode = self:getNode(lastAssign or source.parent)
144203
self.nodes[source] = parentNode or false
145204
return parentNode
146205
end

test/type_inference/init.lua

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1829,6 +1829,17 @@ end
18291829
print(<?x?>)
18301830
]]
18311831

1832+
TEST 'nil' [[
1833+
---@type integer?
1834+
local x
1835+
1836+
if not x then
1837+
print(<?x?>)
1838+
end
1839+
1840+
print(x)
1841+
]]
1842+
18321843
TEST 'integer' [[
18331844
---@type integer?
18341845
local x

0 commit comments

Comments
 (0)