diff options
-rw-r--r-- | script/vm/runner-bak.lua | 444 |
1 files changed, 0 insertions, 444 deletions
diff --git a/script/vm/runner-bak.lua b/script/vm/runner-bak.lua deleted file mode 100644 index 5535f0ca..00000000 --- a/script/vm/runner-bak.lua +++ /dev/null @@ -1,444 +0,0 @@ ----@class vm -local vm = require 'vm.vm' -local guide = require 'parser.guide' - ----@class vm.runner-bak ----@field loc parser.object ----@field mainBlock parser.object ----@field blocks table<parser.object, true> ----@field steps vm.runner.step[] -local mt = {} -mt.__index = mt -mt.index = 1 - ----@class parser.object ----@field _casts parser.object[] - ----@class vm.runner.step ----@field type 'truthy' | 'falsy' | 'as' | 'add' | 'remove' | 'object' | 'save' | 'push' | 'merge' | 'cast' ----@field pos integer ----@field order? integer ----@field node? vm.node ----@field object? parser.object ----@field name? string ----@field cast? parser.object ----@field tag? string ----@field copy? boolean ----@field new? boolean ----@field ref1? vm.runner.step ----@field ref2? vm.runner.step - ----@param filter parser.object ----@param outStep vm.runner.step ----@param blockStep vm.runner.step -function mt:_compileNarrowByFilter(filter, outStep, blockStep) - if not filter then - return - end - if filter.type == 'paren' then - if filter.exp then - self:_compileNarrowByFilter(filter.exp, outStep, blockStep) - end - return - end - if filter.type == 'unary' then - if not filter.op - or not filter[1] then - return - end - if filter.op.type == 'not' then - local exp = filter[1] - if exp.type == 'getlocal' and exp.node == self.loc then - self.steps[#self.steps+1] = { - type = 'falsy', - pos = filter.finish, - new = true, - } - self.steps[#self.steps+1] = { - type = 'truthy', - pos = filter.finish, - ref1 = outStep, - } - end - end - elseif filter.type == 'binary' then - if not filter.op - or not filter[1] - or not filter[2] then - return - end - if filter.op.type == 'and' then - local dummyStep = { - type = 'save', - copy = true, - ref1 = outStep, - pos = filter.start - 1, - } - self.steps[#self.steps+1] = dummyStep - self:_compileNarrowByFilter(filter[1], dummyStep, blockStep) - self:_compileNarrowByFilter(filter[2], dummyStep, blockStep) - end - if filter.op.type == 'or' then - self:_compileNarrowByFilter(filter[1], outStep, blockStep) - local dummyStep = { - type = 'push', - copy = true, - ref1 = outStep, - pos = filter.op.finish, - } - self.steps[#self.steps+1] = dummyStep - self:_compileNarrowByFilter(filter[2], outStep, dummyStep) - self.steps[#self.steps+1] = { - type = 'push', - tag = 'or reset', - ref1 = blockStep, - pos = filter.finish, - } - end - if filter.op.type == '==' - or filter.op.type == '~=' then - local loc, exp - for i = 1, 2 do - loc = filter[i] - if loc.type == 'getlocal' and loc.node == self.loc then - exp = filter[i % 2 + 1] - break - end - end - if not loc or not exp then - return - end - if guide.isLiteral(exp) then - if filter.op.type == '==' then - self.steps[#self.steps+1] = { - type = 'remove', - name = exp.type, - pos = filter.finish, - ref1 = outStep, - } - self.steps[#self.steps+1] = { - type = 'as', - name = exp.type, - pos = filter.finish, - new = true, - } - end - if filter.op.type == '~=' then - self.steps[#self.steps+1] = { - type = 'as', - name = exp.type, - pos = filter.finish, - ref1 = outStep, - } - self.steps[#self.steps+1] = { - type = 'remove', - name = exp.type, - pos = filter.finish, - new = true, - } - end - end - end - else - if filter.type == 'getlocal' and filter.node == self.loc then - self.steps[#self.steps+1] = { - type = 'truthy', - pos = filter.finish, - new = true, - } - self.steps[#self.steps+1] = { - type = 'falsy', - pos = filter.finish, - ref1 = outStep, - } - end - end -end - ----@param block parser.object -function mt:_compileBlock(block) - if self.blocks[block] then - return - end - self.blocks[block] = true - if block == self.mainBlock then - return - end - - local parentBlock = guide.getParentBlock(block) - self:_compileBlock(parentBlock) - - if block.type == 'if' then - ---@type vm.runner.step[] - local finals = {} - for i, childBlock in ipairs(block) do - local blockStep = { - type = 'save', - tag = 'block', - copy = true, - pos = childBlock.start, - } - local outStep = { - type = 'save', - tag = 'out', - copy = true, - pos = childBlock.start, - } - self.steps[#self.steps+1] = blockStep - self.steps[#self.steps+1] = outStep - self.steps[#self.steps+1] = { - type = 'push', - ref1 = blockStep, - pos = childBlock.start, - } - self:_compileNarrowByFilter(childBlock.filter, outStep, blockStep) - if not childBlock.hasReturn - and not childBlock.hasGoTo - and not childBlock.hasBreak then - local finalStep = { - type = 'save', - pos = childBlock.finish, - tag = 'final #' .. i, - } - finals[#finals+1] = finalStep - self.steps[#self.steps+1] = finalStep - end - self.steps[#self.steps+1] = { - type = 'push', - tag = 'reset child', - ref1 = outStep, - pos = childBlock.finish, - } - end - self.steps[#self.steps+1] = { - type = 'push', - tag = 'reset if', - pos = block.finish, - copy = true, - } - for _, final in ipairs(finals) do - self.steps[#self.steps+1] = { - type = 'merge', - ref2 = final, - pos = block.finish, - } - end - end - - if block.type == 'function' - or block.type == 'while' - or block.type == 'loop' - or block.type == 'in' - or block.type == 'repeat' - or block.type == 'for' then - local savePoint = { - type = 'save', - copy = true, - pos = block.start, - } - self.steps[#self.steps+1] = { - type = 'push', - copy = true, - pos = block.start, - } - self.steps[#self.steps+1] = savePoint - self.steps[#self.steps+1] = { - type = 'push', - pos = block.finish, - ref1 = savePoint, - } - end -end - ----@return parser.object[] -function mt:_getCasts() - local root = guide.getRoot(self.loc) - if not root._casts then - root._casts = {} - local docs = root.docs - for _, doc in ipairs(docs) do - if doc.type == 'doc.cast' and doc.loc then - root._casts[#root._casts+1] = doc - end - end - end - return root._casts -end - -function mt:_preCompile() - local startPos = self.loc.start - local finishPos = 0 - - for _, ref in ipairs(self.loc.ref) do - self.steps[#self.steps+1] = { - type = 'object', - object = ref, - pos = ref.range or ref.start, - } - if ref.start > finishPos then - finishPos = ref.start - end - local block = guide.getParentBlock(ref) - self:_compileBlock(block) - end - - for i, step in ipairs(self.steps) do - if step.type ~= 'object' then - step.order = i - end - end - - local casts = self:_getCasts() - for _, cast in ipairs(casts) do - if cast.loc[1] == self.loc[1] - and cast.start > startPos - and cast.finish < finishPos - and guide.getLocal(self.loc, self.loc[1], cast.start) == self.loc then - self.steps[#self.steps+1] = { - type = 'cast', - cast = cast, - pos = cast.start, - } - end - end - - table.sort(self.steps, function (a, b) - if a.pos == b.pos then - return (a.order or 0) < (b.order or 0) - else - return a.pos < b.pos - end - end) -end - ----@param loc parser.object ----@param node vm.node ----@return vm.node -local function checkAssert(loc, node) - local parent = loc.parent - if parent.type == 'binary' then - if parent.op and (parent.op.type == '~=' or parent.op.type == '==') then - local exp - for i = 1, 2 do - if parent[i] == loc then - exp = parent[i % 2 + 1] - end - end - if exp and guide.isLiteral(exp) then - local callargs = parent.parent - if callargs.type == 'callargs' - and callargs.parent.node.special == 'assert' - and callargs[1] == parent then - if parent.op.type == '~=' then - node:remove(exp.type) - end - if parent.op.type == '==' then - node = vm.compileNode(exp) - end - end - end - end - end - if parent.type == 'callargs' - and parent.parent.node.special == 'assert' - and parent[1] == loc then - node:setTruthy() - end - return node -end - ----@param callback fun(src: parser.object, node: vm.node) -function mt:launch(callback) - local topNode = vm.getNode(self.loc):copy() - for _, step in ipairs(self.steps) do - local node = step.ref1 and step.ref1.node or topNode - if step.type == 'truthy' then - if step.new then - node = node:copy() - topNode = node - end - node:setTruthy() - elseif step.type == 'falsy' then - if step.new then - node = node:copy() - topNode = node - end - node:setFalsy() - elseif step.type == 'as' then - if step.new then - topNode = vm.createNode(vm.getGlobal('type', step.name)) - else - node:clear() - node:merge(vm.getGlobal('type', step.name)) - end - elseif step.type == 'add' then - if step.new then - node = node:copy() - topNode = node - end - node:merge(vm.getGlobal('type', step.name)) - elseif step.type == 'remove' then - if step.new then - node = node:copy() - topNode = node - end - node:remove(step.name) - elseif step.type == 'object' then - topNode = callback(step.object, node) or node - if step.object.type == 'getlocal' then - topNode = checkAssert(step.object, node) - end - elseif step.type == 'save' then - if step.copy then - node = node:copy() - end - step.node = node - elseif step.type == 'push' then - if step.copy then - node = node:copy() - end - topNode = node - elseif step.type == 'merge' then - node:merge(step.ref2.node) - elseif step.type == 'cast' then - topNode = node:copy() - for _, cast in ipairs(step.cast.casts) do - if cast.mode == '+' then - if cast.optional then - topNode:addOptional() - end - if cast.extends then - topNode:merge(vm.compileNode(cast.extends)) - end - elseif cast.mode == '-' then - if cast.optional then - topNode:removeOptional() - end - if cast.extends then - topNode:removeNode(vm.compileNode(cast.extends)) - end - else - if cast.extends then - topNode:clear() - topNode:merge(vm.compileNode(cast.extends)) - end - end - end - end - end -end - ----@param loc parser.object ----@return vm.runner -function vm.launchRunner(loc) - local self = setmetatable({ - loc = loc, - mainBlock = guide.getParentBlock(loc), - blocks = {}, - steps = {}, - }, mt) - - self:_preCompile() - - return self -end |