From ede808fe32a66ac828762818bf43d18fc343c159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Wed, 14 Apr 2021 20:13:00 +0800 Subject: stash --- script/core/linker.lua | 100 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 5 deletions(-) (limited to 'script/core/linker.lua') diff --git a/script/core/linker.lua b/script/core/linker.lua index d7f53fa4..6002b22c 100644 --- a/script/core/linker.lua +++ b/script/core/linker.lua @@ -1,4 +1,5 @@ local util = require 'utility' +local guide = require 'parser.guide' local function getKey(source) if source.type == 'local' then @@ -33,6 +34,15 @@ local function checkGlobal(source) return nil end +local function checkLocal(source) + if source.type == 'local' + or source.type == 'setlocal' + or source.type == 'getlocal' then + return true + end + return nil +end + local function checkTableField(source) if source.type == 'table' then return true @@ -56,35 +66,61 @@ local function checkFunctionReturn(source) return nil end +local IDList = {} local function getID(source) if source.type == 'field' or source.type == 'method' then source = source.parent end local current = source - local idList = {} + local index = 0 while true do local id, node = getKey(current) if not id then break end - idList[#idList+1] = id + index = index + 1 + IDList[index] = id source = current if not node then break end current = node end - util.revertTable(idList) - local id = table.concat(idList, '|') + for i = index + 1, #IDList do + IDList[i] = nil + end + util.revertTable(IDList) + local id = table.concat(IDList, '|') return id, current end +---@class link +---@field id string +-- 语法树单元 +---@field source parser.guide.object +-- 是否是局部变量 +---@field loc boolean +-- 是否是全局变量 +---@field global boolean +-- 是否是字面量表中的字段 +---@field tfield boolean +-- 返回值,文件返回值总是0,函数返回值为第几个返回值 +---@field freturn integer + ---创建source的链接信息 +---@param source parser.guide.object +---@return link local function createLink(source) local id, node = getID(source) + if not id then + return nil + end return { - id = id, + id = id, + source = source, + -- 局部变量 + loc = checkLocal(node), -- 全局变量 global = checkGlobal(node), -- 字面量表中的字段 @@ -94,9 +130,31 @@ local function createLink(source) } end +local function insertLinker(linkers, tp, link) + local list = linkers[tp] + local id = link.id + if not list[id] then + list[id] = {} + end + list[id][#list[id]+1] = link + link._linker = list[id] +end + local m = {} +---根据语法树单元获取关联的link列表 +---@param source parser.guide.object +---@return link[]? +function m.getLinkersBySource(source) + if not source._link then + source._link = createLink(source) + end + return source._link and source._link._linker +end + ---获取source的链接信息 +---@param source parser.guide.object +---@return link function m.getLink(source) if not source._link then source._link = createLink(source) @@ -104,4 +162,36 @@ function m.getLink(source) return source._link end +---编译整个文件的link +---@param source parser.guide.object +---@return table +function m.compileLinks(source) + local root = guide.getRoot(source) + if root._linkers then + return root._linkers + end + local linkers = { + loc = {}, + global = {}, + tfield = {}, + } + guide.eachSource(root, function (src) + local link = m.getLink(src) + if not link then + return + end + if link.global then + insertLinker(linkers, 'global', link) + end + if link.loc then + insertLinker(linkers, 'loc', link) + end + if link.tfield then + insertLinker(linkers, 'tfield', link) + end + end) + root._linkers = linkers + return linkers +end + return m -- cgit v1.2.3