Skip to content

Commit 390474c

Browse files
committed
stash
1 parent d74c85c commit 390474c

File tree

6 files changed

+112
-77
lines changed

6 files changed

+112
-77
lines changed

script/parser/guide.lua

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,16 @@ local blockTypes = {
9999
['main'] = true,
100100
}
101101

102+
local topBlockTypes = {
103+
['while'] = true,
104+
['function'] = true,
105+
['if'] = true,
106+
['ifblock'] = true,
107+
['elseblock'] = true,
108+
['elseifblock'] = true,
109+
['main'] = true,
110+
}
111+
102112
local breakBlockTypes = {
103113
['while'] = true,
104114
['in'] = true,
@@ -1250,13 +1260,10 @@ end
12501260
function m.getTopBlock(source)
12511261
for _ = 1, 1000 do
12521262
local block = source.parent
1253-
if not m.isBlockType(block) then
1263+
if not block then
12541264
return nil
12551265
end
1256-
if block.type ~= 'do'
1257-
and block.type ~= 'in'
1258-
and block.type ~= 'loop'
1259-
and block.type ~= 'repeat' then
1266+
if topBlockTypes[block.type] then
12601267
return block
12611268
end
12621269
source = block

script/vm/compiler.lua

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ local function searchFieldByLocalID(source, key, pushResult)
6767
if key then
6868
if source.type == 'variable' then
6969
---@cast source vm.variable
70+
if type(key) ~= 'string' then
71+
return
72+
end
7073
fields = source:getSets(key)
7174
else
7275
---@cast source parser.object
@@ -728,13 +731,13 @@ function vm.selectNode(list, index)
728731
local result
729732
if exp.type == 'call' then
730733
result = getReturn(exp.node, index, exp.args)
731-
if not result:isTyped() then
734+
if result:isEmpty() then
732735
result:merge(vm.declareGlobal('type', 'unknown'))
733736
end
734737
else
735738
---@type vm.node
736739
result = vm.compileNode(exp)
737-
if not result:isTyped() then
740+
if result:isEmpty() then
738741
result:merge(vm.declareGlobal('type', 'unknown'))
739742
end
740743
end
@@ -1233,6 +1236,9 @@ local compilerSwitch = util.switch()
12331236
: case 'getmethod'
12341237
: case 'getindex'
12351238
: call(function (source)
1239+
if bindDocs(source) then
1240+
return
1241+
end
12361242
if guide.isGet(source) and bindAs(source) then
12371243
return
12381244
end
@@ -1257,18 +1263,28 @@ local compilerSwitch = util.switch()
12571263
---@cast k vm.global
12581264
vm.compileByParentNode(source.node, k, function (src)
12591265
vm.setNode(source, vm.compileNode(src))
1260-
if src.value then
1261-
vm.setNode(source, vm.compileNode(src.value))
1262-
end
12631266
end)
12641267
end
12651268
end
12661269
else
12671270
if guide.isGet(source) then
1268-
local node = vm.traceNode(source)
1269-
if node then
1270-
vm.setNode(source, node)
1271-
return
1271+
--local node = vm.traceNode(source)
1272+
--if node then
1273+
-- vm.setNode(source, node)
1274+
--end
1275+
---@cast key string
1276+
vm.compileByParentNode(source.node, key, function (src)
1277+
vm.setNode(source, vm.compileNode(src))
1278+
end)
1279+
else
1280+
local hasDefinedField
1281+
---@cast key string
1282+
vm.compileByParentNode(source.node, key, function (src)
1283+
hasDefinedField = true
1284+
vm.setNode(source, vm.compileNode(src))
1285+
end)
1286+
if not hasDefinedField and source.value then
1287+
vm.setNode(source, vm.compileNode(source.value))
12721288
end
12731289
end
12741290
end
@@ -1767,26 +1783,6 @@ local compilerSwitch = util.switch()
17671783
vm.setNode(variable, vm.compileNode(variable.base))
17681784
return
17691785
end
1770-
local parentVariable = variable:getParent()
1771-
local fieldName = variable:getFieldName()
1772-
if not parentVariable or not fieldName then
1773-
return
1774-
end
1775-
vm.compileByParentNode(parentVariable, fieldName, function (src)
1776-
if src.value then
1777-
if bindDocs(src) then
1778-
vm.setNode(variable, vm.compileNode(src))
1779-
elseif src.value.type ~= 'nil' then
1780-
vm.setNode(variable, vm.compileNode(src.value))
1781-
local node = vm.getNode(src)
1782-
if node then
1783-
vm.setNode(variable, node)
1784-
end
1785-
end
1786-
else
1787-
vm.setNode(variable, vm.compileNode(src))
1788-
end
1789-
end)
17901786
end)
17911787

17921788
---@param source parser.object

script/vm/global.lua

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ local guide = require 'parser.guide'
44
---@class vm
55
local vm = require 'vm.vm'
66

7+
---@type table<string, vm.global>
8+
local allGlobals = {}
9+
---@type table<uri, table<string, boolean>>
10+
local globalSubs = util.multiTable(2)
11+
712
---@class parser.object
813
---@field package _globalBase parser.object
914
---@field package _globalBaseMap table<string, parser.object>
@@ -114,11 +119,39 @@ function mt:getKeyName()
114119
return self.name:match('[^' .. vm.ID_SPLITE .. ']+$')
115120
end
116121

122+
---@return string?
123+
function mt:getFieldName()
124+
return self.name:match(vm.ID_SPLITE .. '(.-)$')
125+
end
126+
117127
---@return boolean
118128
function mt:isAlive()
119129
return next(self.links) ~= nil
120130
end
121131

132+
---@param uri uri
133+
---@return parser.object?
134+
function mt:getParentBase(uri)
135+
local parentID = self.name:match('^(.-)' .. vm.ID_SPLITE)
136+
if not parentID then
137+
return nil
138+
end
139+
local parentName = self.cate .. '|' .. parentID
140+
local global = allGlobals[parentName]
141+
if not global then
142+
return nil
143+
end
144+
local link = global.links[uri]
145+
if not link then
146+
return nil
147+
end
148+
local luckyBoy = link.sets[1] or link.gets[1]
149+
if not luckyBoy then
150+
return nil
151+
end
152+
return vm.getGlobalBase(luckyBoy)
153+
end
154+
122155
---@param cate vm.global.cate
123156
---@return vm.global
124157
local function createGlobal(name, cate)
@@ -138,11 +171,6 @@ end
138171
---@field package _globalNode vm.global|false
139172
---@field package _enums? parser.object[]
140173

141-
---@type table<string, vm.global>
142-
local allGlobals = {}
143-
---@type table<uri, table<string, boolean>>
144-
local globalSubs = util.multiTable(2)
145-
146174
local compileObject
147175
local compilerGlobalSwitch = util.switch()
148176
: case 'local'

script/vm/node.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ end
6161
---@return boolean
6262
function mt:isTyped()
6363
for _, c in ipairs(self) do
64-
if c.type == 'global' and c.cate == 'variable' then
64+
if c.type == 'global' and c.cate == 'type' then
6565
return true
6666
end
6767
if guide.isLiteral(c) then

script/vm/tracer.lua

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ local util = require 'utility'
1212
---@class vm.tracer
1313
---@field mode tracer.mode
1414
---@field name string
15-
---@field source parser.object
16-
---@field variable vm.variable
17-
---@field assigns parser.object[]
15+
---@field source parser.object | vm.variable
16+
---@field assigns (parser.object | vm.variable)[]
1817
---@field assignMap table<parser.object, true>
1918
---@field getMap table<parser.object, true>
2019
---@field careMap table<parser.object, true>
@@ -30,7 +29,7 @@ mt.fastCalc = true
3029

3130
---@return parser.object[]
3231
function mt:getCasts()
33-
local root = guide.getRoot(self.source)
32+
local root = guide.getRoot(self.main)
3433
if not root._casts then
3534
root._casts = {}
3635
local docs = root.docs
@@ -92,12 +91,16 @@ function mt:collectCare(obj)
9291
end
9392

9493
function mt:collectLocal()
95-
local startPos = self.source.start
94+
local startPos = self.source.base.start
9695
local finishPos = 0
9796

98-
local variable = self.variable
97+
local variable = self.source
9998

100-
assert(variable)
99+
if variable.base.type ~= 'local'
100+
and variable.base.type ~= 'self' then
101+
self.assigns[#self.assigns+1] = variable
102+
self.assignMap[self.source] = true
103+
end
101104

102105
for _, set in ipairs(variable.sets) do
103106
self.assigns[#self.assigns+1] = set
@@ -121,18 +124,14 @@ function mt:collectLocal()
121124
if cast.name[1] == self.name
122125
and cast.start > startPos
123126
and cast.finish < finishPos
124-
and vm.getCastTargetHead(cast) == self.source then
127+
and vm.getCastTargetHead(cast) == variable.base then
125128
self.casts[#self.casts+1] = cast
126129
end
127130
end
128131

129132
if #self.casts > 0 then
130133
self.fastCalc = false
131134
end
132-
133-
if variable ~= vm.getVariable(self.source) then
134-
self.fastCalc = false
135-
end
136135
end
137136

138137
function mt:collectGlobal()
@@ -173,17 +172,20 @@ end
173172
---@param finish integer
174173
---@return parser.object?
175174
function mt:getLastAssign(start, finish)
176-
local assign
177-
for _, obj in ipairs(self.assigns) do
178-
if obj.type == 'local'
179-
or obj.type == 'self' then
180-
assign = obj
181-
break
175+
local lastAssign
176+
for _, assign in ipairs(self.assigns) do
177+
local obj
178+
if assign.type == 'variable' then
179+
---@cast assign vm.variable
180+
obj = assign.base
181+
else
182+
---@cast assign parser.object
183+
obj = assign
182184
end
183185
if obj.start < start then
184186
goto CONTINUE
185187
end
186-
if (obj.range or obj.start) >= finish then
188+
if (obj.effect or obj.range or obj.start) >= finish then
187189
break
188190
end
189191
local objBlock = guide.getTopBlock(obj)
@@ -192,11 +194,11 @@ function mt:getLastAssign(start, finish)
192194
end
193195
if objBlock.start <= finish
194196
and objBlock.finish >= finish then
195-
assign = obj
197+
lastAssign = obj
196198
end
197199
::CONTINUE::
198200
end
199-
return assign
201+
return lastAssign
200202
end
201203

202204
---@param pos integer
@@ -656,9 +658,7 @@ local lookIntoChild = util.switch()
656658
and call.type == 'call'
657659
and call.node.special == 'type'
658660
and call.args
659-
and call.args[1]
660-
and call.args[1].type == 'getlocal'
661-
and call.args[1].node == tracer.source then
661+
and tracer.getMap[call.args[1]] then
662662
if action.op.type == '==' then
663663
topNode:narrow(tracer.uri, checker[1])
664664
if outNode then
@@ -790,23 +790,28 @@ end
790790
---@field package _tracer vm.tracer
791791

792792
---@param mode tracer.mode
793-
---@param source parser.object
793+
---@param source parser.object | vm.variable
794794
---@param name string
795-
---@param variable vm.variable?
796795
---@return vm.tracer?
797-
local function createTracer(mode, source, name, variable)
798-
local node = vm.compileNode(variable or source)
796+
local function createTracer(mode, source, name)
797+
local node = vm.compileNode(source)
799798
local tracer = node._tracer
800799
if tracer then
801800
return tracer
802801
end
803-
local main = guide.getParentBlock(source)
802+
local main
803+
if source.type == 'variable' then
804+
---@cast source vm.variable
805+
main = guide.getParentBlock(source.base)
806+
else
807+
---@cast source parser.object
808+
main = guide.getParentBlock(source)
809+
end
804810
if not main then
805811
return nil
806812
end
807813
tracer = setmetatable({
808814
source = source,
809-
variable = variable,
810815
mode = mode,
811816
name = name,
812817
assigns = {},
@@ -833,7 +838,7 @@ end
833838
---@param source parser.object
834839
---@return vm.node?
835840
function vm.traceNode(source)
836-
local mode, base, name, variable
841+
local mode, base, name
837842
if vm.getGlobalNode(source) then
838843
base = vm.getGlobalBase(source)
839844
if not base then
@@ -842,15 +847,14 @@ function vm.traceNode(source)
842847
mode = 'global'
843848
name = base.global:getCodeName()
844849
else
845-
variable = vm.getVariable(source)
846-
if not variable then
850+
base = vm.getVariable(source)
851+
if not base then
847852
return nil
848853
end
849-
base = variable:getBase()
850-
name = variable:getCodeName()
854+
name = base:getCodeName()
851855
mode = 'local'
852856
end
853-
local tracer = createTracer(mode, base, name, variable)
857+
local tracer = createTracer(mode, base, name)
854858
if not tracer then
855859
return nil
856860
end

test/type_inference/init.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3407,7 +3407,7 @@ TEST '{ [string]: number, [true]: string, [1]: boolean, tag: integer }' [[
34073407
local <?t?>
34083408
]]
34093409

3410-
TEST 'unknown' [[
3410+
TEST 'nil' [[
34113411
local mt = {}
34123412
mt.<?x?> = nil
34133413
]]

0 commit comments

Comments
 (0)