From ed97a9e8905fdbb3b23694896c813cfdb73cd91f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Tue, 13 Dec 2022 19:35:43 +0800 Subject: redesign --- script/vm/tracer.lua | 60 +++++++++++++++++++++++++++++--------------- test/type_inference/init.lua | 11 ++++++++ 2 files changed, 51 insertions(+), 20 deletions(-) diff --git a/script/vm/tracer.lua b/script/vm/tracer.lua index 2e2fd084..e304bbd1 100644 --- a/script/vm/tracer.lua +++ b/script/vm/tracer.lua @@ -45,9 +45,7 @@ function mt:collectBlock(obj, mark) return end mark[obj] = true - if obj.type ~= 'do' then - self.assigns[#self.assigns+1] = obj - end + self.assigns[#self.assigns+1] = obj end end @@ -57,6 +55,8 @@ function mt:collectLocal() local mark = {} + self.assigns[#self.assigns+1] = self.source + for _, obj in ipairs(self.source.ref) do if obj.type == 'setlocal' then self.assigns[#self.assigns+1] = obj @@ -79,50 +79,70 @@ function mt:collectLocal() end) end ----@param source parser.object +---@param block parser.object +---@param pos integer ---@return parser.object? -function mt:getLastAssign(source) - local assign = self.source - local block = guide.getParentBlock(source) +function mt:getLastAssign(block, pos) if not block then return nil end + local assign for _, obj in ipairs(self.assigns) do - if obj.start >= source.start then + if obj.start >= pos then break end local objBlock = guide.getParentBlock(obj) if not objBlock then break end - if objBlock == block - or objBlock.type == 'do' - or objBlock.finish > block.finish then + if objBlock == block then assign = obj end end return assign end +---@param source parser.object +---@return vm.node? +function mt:calcNode(source) + if guide.isSet(source) then + local node = vm.compileNode(source) + return node + end + if source.type == 'do' then + local lastAssign = self:getLastAssign(source, source.finish) + if lastAssign then + return self:getNode(lastAssign) + else + return nil + end + end +end + ---@param source parser.object ---@return vm.node? function mt:getNode(source) if self.nodes[source] ~= nil then return self.nodes[source] or nil end - local lastAssign = self:getLastAssign(source) - if not lastAssign then + local parentBlock = guide.getParentBlock(source) + if not parentBlock then + self.nodes[source] = false + return nil + end + if source == self.main then self.nodes[source] = false return nil end - if guide.isSet(lastAssign) then - local lastNode = vm.compileNode(lastAssign) - self.nodes[source] = lastNode - return lastNode + local node = self:calcNode(source) + if node then + self.nodes[source] = node + return node end - local lastNode = self:getNode(lastAssign) - self.nodes[source] = lastNode - return lastNode + local lastAssign = self:getLastAssign(parentBlock, source.start) + local parentNode = self:getNode(lastAssign or parentBlock) + self.nodes[source] = parentNode or false + return parentNode end ---@param source parser.object diff --git a/test/type_inference/init.lua b/test/type_inference/init.lua index ab7404e2..cabff606 100644 --- a/test/type_inference/init.lua +++ b/test/type_inference/init.lua @@ -1767,6 +1767,17 @@ end print() ]] +TEST 'boolean' [[ +local x +x = true +function XX() + do + x = 1 + end +end +print() +]] + TEST 'integer?' [[ ---@type integer? local -- cgit v1.2.3