From 5306630e69f2129fbf7ced43f63ff041f3a513a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Thu, 14 Nov 2019 20:00:11 +0800 Subject: =?UTF-8?q?=E6=9B=B4=E6=96=B0=20parser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server-beta/src/parser/compile.lua | 71 ++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 22 deletions(-) (limited to 'server-beta/src/parser/compile.lua') diff --git a/server-beta/src/parser/compile.lua b/server-beta/src/parser/compile.lua index bf60e7ba..2fdab43d 100644 --- a/server-beta/src/parser/compile.lua +++ b/server-beta/src/parser/compile.lua @@ -1,10 +1,20 @@ local guide = require 'parser.guide' local type = type +local specials = { + ['_G'] = true, + ['rawset'] = true, + ['rawget'] = true, + ['setmetatable'] = true, + ['require'] = true, + ['dofile'] = true, + ['loadfile'] = true, +} + _ENV = nil local LocalLimit = 200 -local pushError, Compile, CompileBlock, Block, GoToTag, ENVMode, Compiled, LocalCount +local pushError, Compile, CompileBlock, Block, GoToTag, ENVMode, Compiled, LocalCount, Version, Special local function addRef(node, obj) if not node.ref then @@ -14,6 +24,14 @@ local function addRef(node, obj) obj.node = node end +local function addSpecial(name, obj) + if not Special[name] then + Special[name] = {} + end + Special[name][#Special[name]+1] = obj + obj.special = name +end + local vmMap = { ['getname'] = function (obj) local loc = guide.getLocal(obj, obj[1], obj.start) @@ -21,6 +39,9 @@ local vmMap = { obj.type = 'getlocal' obj.loc = loc addRef(loc, obj) + if loc.special then + addSpecial(loc.special, obj) + end else obj.type = 'getglobal' if ENVMode == '_ENV' then @@ -29,6 +50,10 @@ local vmMap = { addRef(node, obj) end end + local name = obj[1] + if specials[name] then + addSpecial(name, obj) + end end return obj end, @@ -208,6 +233,9 @@ local vmMap = { obj.localfunction = nil end Compile(obj.value, obj) + if obj.value and obj.value.special then + addSpecial(obj.value.special, obj) + end end, ['setfield'] = function (obj) Compile(obj.node, obj) @@ -250,18 +278,20 @@ local vmMap = { local name = obj[1] local label = guide.getLabel(block, name) if label then - pushError { - type = 'REDEFINED_LABEL', - start = obj.start, - finish = obj.finish, - related = { - { - message = 'REDEFINED_LABEL', - start = label.start, - finish = label.finish, + if Version == 'Lua 5.4' + or block == guide.getBlock(label) then + pushError { + type = 'REDEFINED_LABEL', + start = obj.start, + finish = obj.finish, + relative = { + { + label.start, + label.finish, + } } } - } + end end block.labels[name] = obj end @@ -423,10 +453,7 @@ local function compileGoTo(obj) } return end - if not label.ref then - label.ref = {} - end - label.ref[#label.ref+1] = obj + label.ref = obj -- 如果有局部变量在 goto 与 label 之间声明, -- 并在 label 之后使用,则算作语法错误 @@ -463,16 +490,14 @@ local function compileGoTo(obj) info = { loc = loc[1], }, - related = { + relative = { { - message = 'JUMPED_LABEL', - start = label.start, - finish = label.finish, + start = label.start, + finish = label.finish, }, { - message = 'JUMPED_LOCAL', - start = loc.start, - finish = loc.finish, + start = loc.start, + finish = loc.finish, } }, } @@ -503,6 +528,8 @@ return function (self, lua, mode, version) Compiled = {} GoToTag = {} LocalCount = 0 + Version = version + Special = state.special if type(state.ast) == 'table' then Compile(state.ast) end -- cgit v1.2.3