aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast_opts.lua100
-rw-r--r--src/glum.lua136
-rw-r--r--src/parser_min.lua1216
3 files changed, 924 insertions, 528 deletions
diff --git a/src/ast_opts.lua b/src/ast_opts.lua
new file mode 100644
index 0000000..de49932
--- /dev/null
+++ b/src/ast_opts.lua
@@ -0,0 +1,100 @@
+--[[
+ Optimizatoins for abstract syntax trees
+]]
+local msg = io.write
+--A debugging function, a replacement for glua PrintTable
+local function printtable(tbl, tabset)
+ tabset = tabset or 0
+ for k,v in pairs(tbl) do
+ for i = 0,tabset do msg("\t") end
+ msg(k .. ":")
+ if type(v) == "table" then
+ msg("\n")
+ printtable(v, tabset + 1)
+ else
+ msg(tostring(v) .. "\n")
+ end
+ end
+end
+
+--A function to see if two ast's are equal-ish (does not compare position)
+local function deepcompare(tbl1, tbl2)
+ if type(tbl1) ~= type(tbl2) then return false end
+ for k,v in pairs(tbl1) do
+ print("Checking ", k, " from tbl1")
+ if k == "pos" then goto cont end
+ if type(v) == "table" then
+ print("It is a table! going deeper")
+ if not deepcompare(v,tbl2[k]) then
+ return false
+ end
+ else
+ print("Checking ", v , " against ", tbl2[k])
+ if v ~= tbl2[k] then
+ return false
+ end
+ end
+ ::cont::
+ end
+ return true
+end
+
+local opts = {}
+
+--Optimization 1
+--Folds things with an operator when the fold results in a smaller string
+local foldables = {
+ ["add"] = function(a,b) return a + b end,
+ ["mul"] = function(a,b) return a * b end,
+ ["mod"] = function(a,b) return a % b end,
+ ["sub"] = function(a,b) return a - b end,
+ --["div"] = function(a,b) return a / b end, division has the chance to give us really long strings!
+}
+opts[1] = function(ast)
+ if ast.tag ~= "Op" then return false end
+ local opname = ast[1]
+ local func = foldables[opname]
+ if ast[3] ~= nil and func ~= nil and ast[2].tag == "Number" and ast[3].tag == "Number" then
+ ast.tag = "Number"
+ ast[1] = func(ast[2][1],ast[3][1])
+ for i = 2,#ast do
+ ast[i] = nil
+ end
+ return true
+ end
+ return false
+end
+
+--Optimization 2
+--Find places where we can replace calls with invokes.
+opts[2] = function(ast)
+ if ast.tag == "Call" and ast.pos == 160 then
+ print("Ast:")
+ printtable(ast)
+ print("ast[1][1]")
+ printtable(ast[1][1])
+ print("ast[2]")
+ printtable(ast[2])
+ local dcr = deepcompare(ast[1][1],ast[2])
+ print("Deepcompare:",dcr)
+ --error("stopping")
+ end
+ if ast.tag == "Call" and deepcompare(ast[1][1][1], ast[2][1]) then
+ print("Before correcting for invoke, ast is")
+ printtable(ast)
+ for i = 2,#ast[2] do
+ ast[i] = ast[i+1]
+ end
+ ast.tag = "Invoke"
+ ast[2] = ast[1][2]
+ ast[1] = ast[1][1]
+ print("After correcting for invoke, ast is")
+ printtable(ast)
+
+ --error("Call that should be invoke detected")
+ return true
+ end
+
+end
+
+return opts
diff --git a/src/glum.lua b/src/glum.lua
index f4385c0..bcdd5e6 100644
--- a/src/glum.lua
+++ b/src/glum.lua
@@ -21,18 +21,37 @@ This moudle allows you to minify gLua code
local parser
local msg
+local optimi
if include ~= nil then
parser = include("./parser.lua")
msg = Msg
+ optimi = include("./ast_opts.lua")
else
parser = dofile("../src/parser.lua")
msg = io.write
+ optimi = dofile("../src/ast_opts.lua")
+ print("Just did optimi, it is",type(optimi))
end
local lpeg = require("lpeg")
lpeg.locale(lpeg)
local glum = {}
+--Checks if two tables are the same
+local function deepcompare(tbl1, tbl2)
+ for k,v in pairs(tbl1) do
+ if type(v) == "table" then
+ if not deepcompare(v,tbl2[k]) then
+ return false
+ end
+ else
+ if v ~= tbl2[k] then
+ return false
+ end
+ end
+ end
+end
+
--Creates a deep copy of a table
local function deepcopy(orig)
local orig_type = type(orig)
@@ -125,6 +144,22 @@ local getstringreps = function(ast)
return sstbl
end
+local function astwalker(ast)
+ for i,j in pairs(optimi) do
+ local new = j(ast)
+ changed = changed or new
+ end
+ for k,v in pairs(ast) do
+ if type(v) == "table" then
+ astwalker(v)
+ end
+ end
+ for i,j in pairs(optimi) do
+ local new = j(ast)
+ changed = changed or new
+ end
+end
+
local syntax = {}
local function stringfor(ast,tbl)
@@ -142,10 +177,7 @@ end
syntax = {
["Call"] = function(ast,tbl)
- print("ast for call is")
- printtable(ast)
local exprname = stringfor(ast[1],tbl)
- print("String for expname is",exprname)
last = false
local argnames = {}
local cursor = 2
@@ -213,7 +245,6 @@ syntax = {
["Id"] = function(ast,tbl)
local ret
if last then ret = " " else ret = "" end
- if ast[1] == "pairs" then print("in id, ast1 is pairs") printtable(tbl.ids) end
if tbl.ids[ast[1]] == nil then
ret = ret .. ast[1]
last = true
@@ -225,7 +256,7 @@ syntax = {
end,
["Index"] = function(ast,tbl)
local globalvar = stringfor(ast[1],tbl)
- if ast[2].tag == "String" then
+ if ast[2].tag == "String" and tbl.strings[ast[2][1]] == nil then
last = true
return table.concat({globalvar, ".", ast[2][1]})
end
@@ -243,8 +274,6 @@ syntax = {
return "..."
end,
["Forin"] = function(ast,tbl)
- print("At forin, ast is")
- printtable(ast)
local codetbl = {}
if last then codetbl[1] = " for" else codetbl[1] = "for" end
last = true
@@ -275,17 +304,20 @@ syntax = {
outputtbl[#outputtbl + 1] = stringfor(ast[k])
else
if tbl.ids[ast[k][1]] ~= nil then
+ print("Found id in id table")
outputtbl[#outputtbl + 1] = tbl.ids[ast[k][1]]
else
local newvar = getnextvarname(tbl.lname)
tbl.lname = newvar
tbl.ids[ast[k][1]] = newvar
outputtbl[#outputtbl + 1] = newvar
+ print("Not found, output is ", newvar)
end
last = false
end
end
local output = bef .. table.concat(outputtbl, ",")
+ print("Output from namelist is ", output)
last = true
return output
end,
@@ -307,14 +339,12 @@ syntax = {
return ret
end,
["True"] = function(ast,tbl)
- local ret
- if last then ret = " true" else ret = "true" end
+ local ret = "!!1"
last = true
return ret
end,
["False"] = function(ast,tbl)
- local ret
- if last then ret = " false" else ret = "false" end
+ local ret = "!1"
last = true
return ret
end,
@@ -393,8 +423,8 @@ syntax = {
end,
["Fornum"] = function(ast,tbl)
local spargs = {}
- if last then spargs[1] = " for " else spargs[1] = "for " end
- last = false
+ if last then spargs[1] = " for" else spargs[1] = "for" end
+ last = true
local var
assert(ast[1].tag == "Id","Oh no, I was expecting an ID!")
if ast[1].tag == "Id" then
@@ -424,9 +454,12 @@ syntax = {
local code = ""
spargs[7] = ""
if ast[4].tag ~= "Block" then -- incrementer
+ last = false
incrementer = stringfor(ast[4],tbl)
if incrementer ~= 1 then
spargs[7] = "," .. incrementer
+ else
+ last = true
end
if last then spargs[8] = " do" else spargs[8] = "do" end
last = true
@@ -470,14 +503,14 @@ syntax = {
if uniop[opname] ~= nil then
--Some special case where the parser messes up, fix it here.
--It translates ~= into not ==, but the order of operations makes it so == is evaluated first, and not second.
+ local bef
if opname == "not" and ast[2]["tag"] == "Op" and ast[2][1] == "eq" then
ast[2][1] = "ne"
local ret = stringfor(ast[2],tbl)
return ret
end
- local rhs = stringfor(ast[2],tbl)
- local bef
if last then bef = " " else bef = "" end
+ local rhs = stringfor(ast[2],tbl)
return bef .. uniop[opname] .. rhs
end
local sargs = {}
@@ -578,6 +611,12 @@ syntax = {
return (last and " " or "") .. "goto " .. tbl.nids[ast[1]]
end,
["Function"] = function(ast,tbl)
+ --Sometimes the parser fucks up, correct it here
+ if ast[1][1] ~= nil and ast[1][1].tag == nil then
+ ast[1] = ast[1][1]
+ error("Detected parser fuckup")
+ end
+ --end of parser-fuckup-fix code
local funcstr
if last then funcstr = " function(" else funcstr = "function(" end
last = false
@@ -590,7 +629,39 @@ syntax = {
return table.concat({funcstr,funcargs,")",code,endstr})
end,
["Localrec"] = function(ast,tbl)
- local ident
+ local ident = ast[1][1]
+ local args = ast[2][1][1]
+ local func = ast[2][1][2]
+ local bf = {}
+ if last then bf[1] = " local" else bf[1] = "local" end
+ bf[2] = stringfor(ident,tbl) --ident
+ bf[3] = " function"
+ bf[4] = "("
+ last = false
+ bf[5] = stringfor(args,tbl) --args
+ bf[6] = ")"
+ last = false
+ bf[7] = stringfor(func,tbl) -- function
+ if last then bf[8] = " end" else bf[8] = "end" end
+ last = true
+ return table.concat(bf)
+
+ --[==[
+ --Sometimes the parser fucks up, correct it here
+ print("in localrec, ast is")
+ printtable(ast)
+ if ast[1][1] ~= nil and ast[1].tag == nil then
+ ast[1] = ast[1][1]
+ --error("Detected parser fuckup")
+ print("after fixing fuckup, ast was")
+ printtable(ast)
+ else
+ print("ast[1][1] is",ast[1][1])
+ printtable(ast[1][1])
+ end
+ --end of parser-fuckup-fix code
+ local ident = stringfor(ast[1],tbl)
+ --[=[
if tbl.ids[ast[1][1]] ~= nil then
ident = tbl.ids[ast[1][1]]
else
@@ -599,6 +670,7 @@ syntax = {
tbl.ids[ast[1][1][1]] = newvar
ident = newvar
end
+ ]=]
local locfuncstr
if last then locfuncstr = " local function " else locfuncstr = "local function " end
last = false
@@ -612,6 +684,7 @@ syntax = {
print(string.format("At localrec, locfuncstr:%q ident:%q argstr:%q expr:%q endstr:%q last:%q",locfuncstr,ident,argstr,expr,endstr,tostring(last)))
--print("Found 1 local as Localrec")
return table.concat({locfuncstr,ident,"(",argstr,")",expr,endstr})
+ ]==]
end,
["Continue"] = function(ast,tbl)
local ret
@@ -653,34 +726,6 @@ syntax = {
end,
}
-
-
---Removes extra spaces and duplicated ; from a string
---[[
-local function removespaces(str)
- local removables = {
- {"%s*%)%s*","%)"}, --Spaces before or after )
- {"%s*%(%s*","%("}, --Spaces before or after (
- {"%s*;%s*",";"}, --Spaces before or after ;
- {"%s*,%s*",","}, --Spaces before or after ,
- {";+",";"}, --Multiple ; in a row
- {"^%s*",""}, --Spaces at the beginning of the file
- {"%s*$",""}, --Spaces at the end of the file
- {"%s+"," "}, --Multiple spaces in a row
- }
- --Order is important
- for k,v in ipairs(removables) do
- str = string.gsub(str,v[1],v[2])
- end
- return str
-end
-]]
-
---Compress the string, and adds a little decompression code at the top.
---local function compress(str)
---
---end
-
glum.minify = function(str, name)
name = name or "anonymous"
local ast, error_msg = parser.parse(str, name)
@@ -688,7 +733,8 @@ glum.minify = function(str, name)
error(error_msg)
return nil
end
- print("in glum.minify, ast is ")
+ astwalker(ast)
+ print("After astwalker, ast is")
printtable(ast)
print("Finding string reps")
local strreps = getstringreps(ast)
diff --git a/src/parser_min.lua b/src/parser_min.lua
index a627cc4..8750cfd 100644
--- a/src/parser_min.lua
+++ b/src/parser_min.lua
@@ -1,554 +1,804 @@
local a, b, d, e, c = "String", "errorinfo", "function", "cannot use '...' outside a vararg function", "SuffixedExp"
- local f = {}
- local g = require("lpeg")
- local h
-
- if include ~= nil then
- h = include("./scope.lua")
- else
- h = dofile("../src/scope.lua")
+local f = {}
+local g = require("lpeg")
+local h
+
+if include ~= nil then
+ h = include("./scope.lua")
+else
+ h = dofile("../src/scope.lua")
+end
+
+g.locale(g)
+local i, j, k = g.P, g.S, g.V
+local l, m, n, o = g.C, g.Carg, g.Cb, g.Cc
+local p, q, r, s, t = g.Cf, g.Cg, g.Cmt, g.Cp, g.Ct
+local u, v, w = g.alpha, g.digit, g.alnum
+local x = g.xdigit
+local y = g.space
+local z = h.lineno
+local A, B = h.new_scope, h.end_scope
+local C, D = h.new_function, h.end_function
+local E, F = h.begin_loop, h.end_loop
+local G = h.insideloop
+local H = g.P("/*")
+local I = g.P("*/")
+local J = (1 - H) ^ 0
+local K = (1 - I) ^ 0
+local L = H * K * I
+
+local function M(N, O, P)
+ local Q, R = z(N.subject, O)
+ local S = "%s:%d:%d: syntax error, %s"
+
+ return string.format(S, N.filename, Q, R, P)
+end
+
+local function Q(R, S, T)
+ return T.ffp or S, T
+end
+
+local function U()
+ return r(m(1), Q) * (l(k("OneWord")) + o("EOF")) / function(T, V)
+ T.unexpected = V
+
+ return T
end
+end
- g.locale(g)
- local i, j, k = g.P, g.S, g.V
- local l, m, n, o = g.C, g.Carg, g.Cb, g.Cc
- local p, q, r, s, t = g.Cf, g.Cg, g.Cmt, g.Cp, g.Ct
- local u, v, w = g.alpha, g.digit, g.alnum
- local x = g.xdigit
- local y = g.space
- local z = h.lineno
- local A, B = h.new_scope, h.end_scope
- local C, D = h.new_function, h.end_function
- local E, F = h.begin_loop, h.end_loop
- local G = h.insideloop
- local H = g.P("/*")
- local I = g.P("*/")
- local J = (1 - H) ^ 0
- local K = (1 - I) ^ 0
- local L = H * K * I
-
- local function M(N, O, P)
- local Q, R = z(N.subject, O)
- local S = "%s:%d:%d: syntax error, %s"
-
- return string.format(S, N.filename, Q, R, P)
+local function V()
+ return U() / function(T)
+ local W = T.ffp or 1
+ local P = "unexpected '%s', expecting %s"
+ P = string.format(P, T.unexpected, T.expected)
+
+ return nil, M(T, W, P)
+ end
+end
+
+local function W()
+ return V()
+end
+
+local function X(R, S, T, Y)
+ if not T.ffp or T.ffp < S then
+ T.ffp = S
+ T.list = {}
+ T.list[Y] = Y
+ T.expected = "'" .. Y .. "'"
+ elseif S == T.ffp then
end
- local function Q(R, S, T)
- return T.ffp or S, T
+ return false
+end
+
+local function Z(aa)
+ return r(m(1) * o(aa), X)
+end
+
+local function ba(ca)
+ ca = string.gsub(ca, "\\a", "\a")
+ ca = string.gsub(ca, "\\b", "\b")
+ ca = string.gsub(ca, "\\f", "\f")
+ ca = string.gsub(ca, "\\n", "\n")
+ ca = string.gsub(ca, "\\r", "\r")
+ ca = string.gsub(ca, "\\t", "\t")
+ ca = string.gsub(ca, "\\v", "\v")
+ ca = string.gsub(ca, "\\\n", "\n")
+ ca = string.gsub(ca, "\\\r", "\n")
+ ca = string.gsub(ca, "\\'", "'")
+ ca = string.gsub(ca, [[\\"]], [["]])
+ ca = string.gsub(ca, "\\\\", "\\")
+
+ return ca
+end
+
+local function da(ea, aa)
+ return ea * k("Skip") + Z(aa) * i(false)
+end
+
+local function fa(ca)
+ return da(i(ca), ca)
+end
+
+local function ga(ca)
+ return da(i(ca) * -k("idRest"), ca)
+end
+
+local function ha(ia, ea)
+ return t(q(s(), "pos") * q(o(ia), "tag") * ea)
+end
+
+local function ja(ka, la)
+ return {
+ ["tag"] = "Op",
+ ["pos"] = la.pos,
+ [1] = ka,
+ [2] = la
+ }
+end
+
+local function ma(na, ka, oa)
+ if not ka then
+ return na
+ elseif ka == "add" then
+ orka"sub"
+ orka"mul"
+ orka"div"
+ orka"idiv"
+ orka"mod"
+ orka"pow"
+ orka"concat"
+ orka"band"
+ orka"bor"
+ orka"bxor"
+ orka"shl"
+ orka"shr"
+ orka"eq"
+ orka"lt"
+ orka"le"
+ orka"and"
+ orka"or"
+ elseif ka == "ne" then
+ elseif ka == "gt" then
+ elseif ka == "ge" then
end
+end
+
+local function pa(ea, qa, ra)
+ return p(ea * q(qa * ea) ^ 0, ma) + ra
+end
+
+local function sa(ea, qa)
+ return p(ea * q(qa * ea) ^ 0, ma)
+end
+
+local function ta(ea, qa, ia)
+ return ha(ia, (ea * (qa * ea) ^ 0) ^ (-1))
+end
+
+local function ua(ea, qa, ia)
+ return ha(ia, ea * (qa * ea) ^ 0)
+end
+
+local va = {
+ k("Lua"),
+ ["Lua"] = k("Shebang") ^ (-1) * k("Skip") * k("Chunk") * -1 + W(),
+ ["Chunk"] = k("Block"),
+ ["StatList"] = (fa(";") + k("Stat")) ^ 0,
+ ["Var"] = k("Id"),
+ ["Id"] = ha("Id", da(k("Name"), "Name")),
+ ["FunctionDef"] = ga(d) * k("FuncBody"),
+ ["FieldSep"] = fa(",") + fa(";"),
+ ["Field"] = ha("Pair", (fa("[") * k("Expr") * fa("]") * fa("=") * k("Expr")) + (ha(a, da(k("Name"), "Name")) * fa("=") * k("Expr"))) + k("Expr"),
+ ["FieldList"] = (k("Field") * (k("FieldSep") * k("Field")) ^ 0 * k("FieldSep") ^ (-1)) ^ (-1),
+ ["Constructor"] = ha("Table", fa("{") * k("FieldList") * fa("}")),
+ ["NameList"] = ua(k("Id"), fa(","), "NameList"),
+ ["ExpList"] = ua(k("Expr"), fa(","), "ExpList"),
+ ["FuncArgs"] = fa("(") * (k("Expr") * (fa(",") * k("Expr")) ^ 0) ^ (-1) * fa(")") + k("Constructor") + ha(a, da(k(a), a)),
+ ["Expr"] = k("SubExpr_1"),
+ ["SubExpr_1"] = sa(k("SubExpr_2"), k("OrOp")),
+ ["SubExpr_2"] = sa(k("SubExpr_3"), k("AndOp")),
+ ["SubExpr_3"] = sa(k("SubExpr_4"), k("RelOp")),
+ ["SubExpr_4"] = sa(k("SubExpr_5"), k("BOrOp")),
+ ["SubExpr_5"] = sa(k("SubExpr_6"), k("BXorOp")),
+ ["SubExpr_6"] = sa(k("SubExpr_7"), k("BAndOp")),
+ ["SubExpr_7"] = sa(k("SubExpr_8"), k("ShiftOp")),
+ ["SubExpr_8"] = k("SubExpr_9") * k("ConOp") * k("SubExpr_8") / ma + k("SubExpr_9"),
+ ["SubExpr_9"] = sa(k("SubExpr_10"), k("AddOp")),
+ ["SubExpr_10"] = sa(k("SubExpr_11"), k("MulOp")),
+ ["SubExpr_11"] = k("UnOp") * k("SubExpr_11") / ja + k("SubExpr_12"),
+ ["SubExpr_12"] = k("SimpleExp") * (k("PowOp") * k("SubExpr_11")) ^ (-1) / ma,
+ ["SimpleExp"] = ha("Number", da(k("Number"), "Number")) + ha(a, da(k(a), a)) + ha("Nil", ga("nil")) + ha("False", ga("false")) + ha("True", ga("true")) + ha("Dots", fa("...")) + k("FunctionDef") + k("Constructor") + k(c),
+ [c] = p(k("PrimaryExp") * (ha("DotIndex", fa(".") * ha(a, da(k("Name"), "Name"))) + ha("ArrayIndex", fa("[") * k("Expr") * fa("]")) + ha("Invoke", q(fa(":") * ha(a, da(k("Name"), "Name")) * k("FuncArgs"))) + ha("Call", k("FuncArgs"))) ^ 0, function(wa, xa)
+ if xa then
+ if xa.tag == "Call" then
+ orxa.tag"Invoke"
+
+ local T = {
+ ["tag"] = xa.tag,
+ ["pos"] = wa.pos,
+ [1] = wa
+ }
- local function U()
- return r(m(1), Q) * (l(k("OneWord")) + o("EOF")) / function(T, V)
- T.unexpected = V
+ for ya, za in ipairs(xa) do
+ table.insert(T, za)
+ end
- return T
+ return T
+ else
+ return {
+ ["tag"] = "Index",
+ ["pos"] = wa.pos,
+ [1] = wa,
+ [2] = xa[1]
+ }
+ end
end
- end
- local function V()
- return U() / function(T)
- local W = T.ffp or 1
- local P = "unexpected '%s', expecting %s"
- P = string.format(P, T.unexpected, T.expected)
+ return wa
+ end),
+ ["PrimaryExp"] = k("Var") + ha("Paren", fa("(") * k("Expr") * fa(")")),
+ ["Block"] = ha("Block", k("StatList") * k("RetStat") ^ (-1)),
+ ["IfStat"] = ha("If", ga("if") * k("Expr") * ga("then") * k("Block") * (ga("elseif") * k("Expr") * ga("then") * k("Block")) ^ 0 * (ga("else") * k("Block")) ^ (-1) * ga("end")),
+ ["WhileStat"] = ha("While", ga("while") * k("Expr") * ga("do") * k("Block") * ga("end")),
+ ["DoStat"] = ga("do") * k("Block") * ga("end") / function(T)
+ T.tag = "Do"
+
+ return T
+ end,
+ ["ForBody"] = ga("do") * k("Block"),
+ ["ForNum"] = ha("Fornum", k("Id") * fa("=") * k("Expr") * fa(",") * k("Expr") * (fa(",") * k("Expr")) ^ (-1) * k("ForBody")),
+ ["ForGen"] = ha("Forin", k("NameList") * ga("in") * k("ExpList") * k("ForBody")),
+ ["ForStat"] = ga("for") * (k("ForNum") + k("ForGen")) * ga("end"),
+ ["RepeatStat"] = ha("Repeat", ga("repeat") * k("Block") * ga("until") * k("Expr")),
+ ["FuncName"] = p(k("Id") * (fa(".") * ha(a, da(k("Name"), "Name"))) ^ 0, function(wa, xa)
+ if xa then
+ return {
+ ["tag"] = "Index",
+ ["pos"] = wa.pos,
+ [1] = wa,
+ [2] = xa
+ }
+ end
- return nil, M(T, W, P)
- end
- end
+ return wa
+ end) * (fa(":") * ha(a, da(k("Name"), "Name"))) ^ (-1) / function(wa, xa)
+ if xa then
+ return {
+ ["tag"] = "Index",
+ ["pos"] = wa.pos,
+ ["is_method"] = true,
+ [1] = wa,
+ [2] = xa
+ }
+ end
- local function W()
- return V()
- end
+ return wa
+ end,
+ ["ParList"] = k("NameList") * (fa(",") * fa("...") * ha("Dots", s())) ^ (-1) / function(T, ya)
+ if ya then
+ table.insert(T, ya)
+ end
- local function X(R, S, T, Y)
- if not T.ffp or T.ffp < S then
- T.ffp = S
- T.list = {}
- T.list[Y] = Y
- T.expected = "'" .. Y .. "'"
- elseif S == T.ffp then
- end
+ return T
+ end + fa("...") * ha("Dots", s()) / function(ya) return {ya} end + i(true) / function() return {} end,
+ ["FuncBody"] = ha("Function", fa("(") * k("ParList") * fa(")") * k("Block") * ga("end")),
+ ["FuncStat"] = ha("Set", ga(d) * k("FuncName") * k("FuncBody")) / function(T)
+ if T[1].is_method then
+ table.insert(T[2][1], 1, {
+ ["tag"] = "Id",
+ [1] = "self"
+ })
+ end
- return false
- end
+ T[1] = {T[1]}
+ T[2] = {T[2]}
+
+ return T
+ end,
+ ["LocalFunc"] = ha("Localrec", ga(d) * k("Id") * k("FuncBody")) / function(T)
+ T[1] = {T[1]}
+ T[2] = {T[2]}
+
+ return T
+ end,
+ ["LocalAssign"] = ha("Local", k("NameList") * ((fa("=") * k("ExpList")) + t(o()))),
+ ["LocalStat"] = ga("local") * (k("LocalFunc") + k("LocalAssign")),
+ ["LabelStat"] = ha("Label", fa("::") * da(k("Name"), "Name") * fa("::")),
+ ["BreakStat"] = ha("Break", ga("break")),
+ ["ContinueStat"] = ha("Continue", ga("continue")),
+ ["GoToStat"] = ha("Goto", ga("goto") * da(k("Name"), "Name")),
+ ["RetStat"] = ha("Return", ga("return") * (k("Expr") * (fa(",") * k("Expr")) ^ 0) ^ (-1) * fa(";") ^ (-1)),
+ ["ExprStat"] = r((k(c) * (o(function()
+ local za = {...}
+ local Aa = za[#za]
+ table.remove(za)
+
+ for Ba, ya in ipairs(za) do
+ if ya.tag == "Id" then
+ orya.tag"Index"
+ else
+ za[Ba] = ya
- local function Z(aa)
- return r(m(1) * o(aa), X)
- end
+ return false
+ end
+ end
- local function ba(ca)
- ca = string.gsub(ca, "\\a", "\a")
- ca = string.gsub(ca, "\\b", "\b")
- ca = string.gsub(ca, "\\f", "\f")
- ca = string.gsub(ca, "\\n", "\n")
- ca = string.gsub(ca, "\\r", "\r")
- ca = string.gsub(ca, "\\t", "\t")
- ca = string.gsub(ca, "\\v", "\v")
- ca = string.gsub(ca, "\\\n", "\n")
- ca = string.gsub(ca, "\\\r", "\n")
- ca = string.gsub(ca, "\\'", "'")
- ca = string.gsub(ca, [[\\"]], [["]])
- ca = string.gsub(ca, "\\\\", "\\")
-
- return ca
- end
+ za.tag = "VarList"
+ za.pos = za[1].pos
- local function da(ea, aa)
- return ea * k("Skip") + Z(aa) * i(false)
- end
+ return true, {
+ ["tag"] = "Set",
+ ["pos"] = za.pos,
+ [1] = za,
+ [2] = Aa
+ }
+ end) * k("Assignment"))) + (k(c) * (o(function(R)
+ if R.tag == "Call" then
+ orR.tag"Invoke"
+ else
+ return true, R
+ end
- local function fa(ca)
- return da(i(ca), ca)
- end
+ return false
+ end))), function(R, S, za, Aa, ...) return Aa(za, ...) end),
+ ["Assignment"] = ((fa(",") * k(c)) ^ 1) ^ (-1) * fa("=") * k("ExpList"),
+ ["Stat"] = k("IfStat") + k("WhileStat") + k("DoStat") + k("ForStat") + k("RepeatStat") + k("FuncStat") + k("LocalStat") + k("LabelStat") + k("BreakStat") + k("GoToStat") + k("ExprStat") + k("ContinueStat"),
+ ["Space"] = y ^ 1,
+ ["Equals"] = i("=") ^ 0,
+ ["Open"] = "[" * q(k("Equals"), "init") * "[" * i("\n") ^ (-1),
+ ["Close"] = "]" * l(k("Equals")) * "]",
+ ["CloseEQ"] = r(k("Close") * n("init"), function(R, S, ra, Ba) return ra == Ba end),
+ ["LongString"] = k("Open") * l((i(1) - k("CloseEQ")) ^ 0) * k("Close") / function(R, Ca) return R end,
+ ["Comment"] = i("--") * k("LongString") / function() return end + i("--") * (i(1) - i("\n")) ^ 0 + i("//") * (i(1) - i("\n")) ^ 0 + l(L) / function() return end,
+ ["Skip"] = (k("Space") + k("Comment")) ^ 0,
+ ["idStart"] = u + i("_"),
+ ["idRest"] = w + i("_"),
+ ["Keywords"] = i("and") + "break" + "do" + "elseif" + "else" + "end" + "false" + "for" + d + "goto" + "if" + "in" + "local" + "nil" + "not" + "or" + "repeat" + "return" + "then" + "true" + "until" + "while" + "continue",
+ ["Reserved"] = k("Keywords") * -k("idRest"),
+ ["Identifier"] = k("idStart") * k("idRest") ^ 0,
+ ["Name"] = -k("Reserved") * l(k("Identifier")) * -k("idRest"),
+ ["Hex"] = (i("0x") + i("0X")) * x ^ 1,
+ ["Expo"] = j("eE") * j("+-") ^ (-1) * v ^ 1,
+ ["Float"] = (((v ^ 1 * i(".") * v ^ 0) + (i(".") * v ^ 1)) * k("Expo") ^ (-1)) + (v ^ 1 * k("Expo")),
+ ["Int"] = v ^ 1,
+ ["Number"] = l(k("Hex") + k("Float") + k("Int")) / function(Y) return tonumber(Y) end,
+ ["ShortString"] = i([["]]) * l(((i("\\") * i(1)) + (i(1) - i([["]]))) ^ 0) * i([["]]) + i("'") * l(((i("\\") * i(1)) + (i(1) - i("'"))) ^ 0) * i("'"),
+ [a] = k("LongString") + (k("ShortString") / function(R) return R end),
+ ["OrOp"] = ga("or") / "or" + fa("||") / "or",
+ ["AndOp"] = ga("and") / "and" + fa("&&") / "and",
+ ["RelOp"] = fa("~=") / "ne" + fa("==") / "eq" + fa("<=") / "le" + fa(">=") / "ge" + fa("<") / "lt" + fa(">") / "gt" + fa("!=") / "ne",
+ ["BOrOp"] = fa("|") / "bor",
+ ["BXorOp"] = fa("~") / "bxor",
+ ["BAndOp"] = fa("&") / "band",
+ ["ShiftOp"] = fa("<<") / "shl" + fa(">>") / "shr",
+ ["ConOp"] = fa("..") / "concat",
+ ["AddOp"] = fa("+") / "add" + fa("-") / "sub",
+ ["MulOp"] = fa("*") / "mul" + fa("/") / "div" + fa("%") / "mod",
+ ["UnOp"] = ga("not") / "not" + fa("-") / "unm" + fa("#") / "len" + fa("~") / "bnot" + fa("!") / "not",
+ ["PowOp"] = fa("^") / "pow",
+ ["Shebang"] = i("#") * (i(1) - i("\n")) ^ 0 * i("\n"),
+ ["OneWord"] = k("Name") + k("Number") + k(a) + k("Reserved") + i("...") + i(1)
+ }
+
+ local function Da(Ea, h, Fa)
+ local Ga = Fa[1]
+ forR = h
+
+ do
+ if Ea[R].label[Ga] then return true end
+ end
- local function ga(ca)
- return da(i(ca) * -k("idRest"), ca)
- end
+ return false
+ end
- local function ha(ia, ea)
- return t(q(s(), "pos") * q(o(ia), "tag") * ea)
- end
+ local function Ga(Ea, Ha, O)
+ local h = Ea.scope
+ local Ia = Ea[h].label[Ha]
- local function ja(ka, la)
- return {
- ["tag"] = "Op",
- ["pos"] = la.pos,
- [1] = ka,
- [2] = la
- }
- end
+ if not Ia then
+ Ea[h].label[Ha] = {
+ ["name"] = Ha,
+ ["pos"] = O
+ }
- local function ma(na, ka, oa)
- if not ka then
- return na
- elseif ka == "add" then
- orka"sub"
- orka"mul"
- orka"div"
- orka"idiv"
- orka"mod"
- orka"pow"
- orka"concat"
- orka"band"
- orka"bor"
- orka"bxor"
- orka"shl"
- orka"shr"
- orka"eq"
- orka"lt"
- orka"le"
- orka"and"
- orka"or"
- elseif ka == "ne" then
- elseif ka == "gt" then
- elseif ka == "ge" then
- end
- end
+ return true
+ else
+ local P = "label '%s' already defined at line %d"
+ local Ja = z(Ea.errorinfo.subject, Ia.pos)
+ P = string.format(P, Ha, Ja)
- local function pa(ea, qa, ra)
- return p(ea * q(qa * ea) ^ 0, ma) + ra
- end
+ return nil, M(Ea.errorinfo, O, P)
+ end
+ end
- local function sa(ea, qa)
- return p(ea * q(qa * ea) ^ 0, ma)
- end
+ local function Ia(Ea, Fa)
+ local h = Ea.scope
+ table.insert(Ea[h].goto, Fa)
- local function ta(ea, qa, ia)
- return ha(ia, (ea * (qa * ea) ^ 0) ^ (-1))
- end
+ return true
+ end
- local function ua(ea, qa, ia)
- return ha(ia, ea * (qa * ea) ^ 0)
- end
+ local function Ja(Ea)
+ forR = Ea.maxscope
- local va = {
- k("Lua"),
- ["Lua"] = k("Shebang") ^ (-1) * k("Skip") * k("Chunk") * -1 + W(),
- ["Chunk"] = k("Block"),
- ["StatList"] = (fa(";") + k("Stat")) ^ 0,
- ["Var"] = k("Id"),
- ["Id"] = ha("Id", da(k("Name"), "Name")),
- ["FunctionDef"] = ga(d) * k("FuncBody"),
- ["FieldSep"] = fa(",") + fa(";"),
- ["Field"] = ha("Pair", (fa("[") * k("Expr") * fa("]") * fa("=") * k("Expr")) + (ha(a, da(k("Name"), "Name")) * fa("=") * k("Expr"))) + k("Expr"),
- ["FieldList"] = (k("Field") * (k("FieldSep") * k("Field")) ^ 0 * k("FieldSep") ^ (-1)) ^ (-1),
- ["Constructor"] = ha("Table", fa("{") * k("FieldList") * fa("}")),
- ["NameList"] = ua(k("Id"), fa(","), "NameList"),
- ["ExpList"] = ua(k("Expr"), fa(","), "ExpList"),
- ["FuncArgs"] = fa("(") * (k("Expr") * (fa(",") * k("Expr")) ^ 0) ^ (-1) * fa(")") + k("Constructor") + ha(a, da(k(a), a)),
- ["Expr"] = k("SubExpr_1"),
- ["SubExpr_1"] = sa(k("SubExpr_2"), k("OrOp")),
- ["SubExpr_2"] = sa(k("SubExpr_3"), k("AndOp")),
- ["SubExpr_3"] = sa(k("SubExpr_4"), k("RelOp")),
- ["SubExpr_4"] = sa(k("SubExpr_5"), k("BOrOp")),
- ["SubExpr_5"] = sa(k("SubExpr_6"), k("BXorOp")),
- ["SubExpr_6"] = sa(k("SubExpr_7"), k("BAndOp")),
- ["SubExpr_7"] = sa(k("SubExpr_8"), k("ShiftOp")),
- ["SubExpr_8"] = k("SubExpr_9") * k("ConOp") * k("SubExpr_8") / ma + k("SubExpr_9"),
- ["SubExpr_9"] = sa(k("SubExpr_10"), k("AddOp")),
- ["SubExpr_10"] = sa(k("SubExpr_11"), k("MulOp")),
- ["SubExpr_11"] = k("UnOp") * k("SubExpr_11") / ja + k("SubExpr_12"),
- ["SubExpr_12"] = k("SimpleExp") * (k("PowOp") * k("SubExpr_11")) ^ (-1) / ma,
- ["SimpleExp"] = ha("Number", da(k("Number"), "Number")) + ha(a, da(k(a), a)) + ha("Nil", ga("nil")) + ha("False", ga("false")) + ha("True", ga("true")) + ha("Dots", fa("...")) + k("FunctionDef") + k("Constructor") + k(c),
- [c] = p(k("PrimaryExp") * (ha("DotIndex", fa(".") * ha(a, da(k("Name"), "Name"))) + ha("ArrayIndex", fa("[") * k("Expr") * fa("]")) + ha("Invoke", q(fa(":") * ha(a, da(k("Name"), "Name")) * k("FuncArgs"))) + ha("Call", k("FuncArgs"))) ^ 0, function(wa, xa)
- if xa then
- if xa.tag == "Call" then
- orxa.tag"Invoke"
-
- local T = {
- ["tag"] = xa.tag,
- ["pos"] = wa.pos,
- [1] = wa
- }
+ do
+ for Ka, ya in ipairs(Ea[R].goto) do
+ if not Da(Ea, R, ya) then
+ local P = "no visible label '%s' for <goto>"
+ P = string.format(P, ya[1])
- for ya, za in ipairs(xa) do
- table.insert(T, za)
+ return nil, M(Ea.errorinfo, ya.pos, P)
+ end
end
+ end
- return T
- else
- return {
- ["tag"] = "Index",
- ["pos"] = wa.pos,
- [1] = wa,
- [2] = xa[1]
- }
+ return true
+ end
+
+ local function Ka(Ea, La)
+ Ea.Ea.fscope.is_vararg = La
+ end
+
+ local Ma, Na, Oa
+ local Pa, Qa, Ra, Sa
+
+ Sa = function(Ea, Ta)
+ local Ua = #Ta
+ local La = false
+
+ if 0 < Ua and Ta[Ua].tag == "Dots" then
+ La = true
end
+
+ Ka(Ea, La)
+
+ return true
end
- return wa
- end),
- ["PrimaryExp"] = k("Var") + ha("Paren", fa("(") * k("Expr") * fa(")")),
- ["Block"] = ha("Block", k("StatList") * k("RetStat") ^ (-1)),
- ["IfStat"] = ha("If", ga("if") * k("Expr") * ga("then") * k("Block") * (ga("elseif") * k("Expr") * ga("then") * k("Block")) ^ 0 * (ga("else") * k("Block")) ^ (-1) * ga("end")),
- ["WhileStat"] = ha("While", ga("while") * k("Expr") * ga("do") * k("Block") * ga("end")),
- ["DoStat"] = ga("do") * k("Block") * ga("end") / function(T)
- T.tag = "Do"
-
- return T
- end,
- ["ForBody"] = ga("do") * k("Block"),
- ["ForNum"] = ha("Fornum", k("Id") * fa("=") * k("Expr") * fa(",") * k("Expr") * (fa(",") * k("Expr")) ^ (-1) * k("ForBody")),
- ["ForGen"] = ha("Forin", k("NameList") * ga("in") * k("ExpList") * k("ForBody")),
- ["ForStat"] = ga("for") * (k("ForNum") + k("ForGen")) * ga("end"),
- ["RepeatStat"] = ha("Repeat", ga("repeat") * k("Block") * ga("until") * k("Expr")),
- ["FuncName"] = p(k("Id") * (fa(".") * ha(a, da(k("Name"), "Name"))) ^ 0, function(wa, xa)
- if xa then
- return {
- ["tag"] = "Index",
- ["pos"] = wa.pos,
- [1] = wa,
- [2] = xa
- }
- end
+ local function Ua(Ea, Va)
+ C(Ea)
+ A(Ea)
+ local Wa, P = Sa(Ea, Va[1])
+ if not Wa then return Wa, P end
+ Wa, P, Wa, P = Pa(Ea, Va[2])
+ if not Wa then return Wa, P end
+ B(Ea)
+ D(Ea)
+
+ return true
+ end
- return wa
- end) * (fa(":") * ha(a, da(k("Name"), "Name"))) ^ (-1) / function(wa, xa)
- if xa then
- return {
- ["tag"] = "Index",
- ["pos"] = wa.pos,
- ["is_method"] = true,
- [1] = wa,
- [2] = xa
- }
- end
+ local function Wa(Ea, Va)
+ local Xa, P = Na(Ea, Va[2])
+ if not Xa then return Xa, P end
- return wa
- end,
- ["ParList"] = k("NameList") * (fa(",") * fa("...") * ha("Dots", s())) ^ (-1) / function(T, ya)
- if ya then
- table.insert(T, ya)
- end
+ if Va[3] then
+ Xa, P, Xa, P = Na(Ea, Va[3])
+ if not Xa then return Xa, P end
+ end
- return T
- end + fa("...") * ha("Dots", s()) / function(ya) return {ya} end + i(true) / function() return {} end,
- ["FuncBody"] = ha("Function", fa("(") * k("ParList") * fa(")") * k("Block") * ga("end")),
- ["FuncStat"] = ha("Set", ga(d) * k("FuncName") * k("FuncBody")) / function(T)
- if T[1].is_method then
- table.insert(T[2][1], 1, {
- ["tag"] = "Id",
- [1] = "self"
- })
- end
+ return true
+ end
- T[1] = {T[1]}
- T[2] = {T[2]}
-
- return T
- end,
- ["LocalFunc"] = ha("Localrec", ga(d) * k("Id") * k("FuncBody")) / function(T)
- T[1] = {T[1]}
- T[2] = {T[2]}
-
- return T
- end,
- ["LocalAssign"] = ha("Local", k("NameList") * ((fa("=") * k("ExpList")) + t(o()))),
- ["LocalStat"] = ga("local") * (k("LocalFunc") + k("LocalAssign")),
- ["LabelStat"] = ha("Label", fa("::") * da(k("Name"), "Name") * fa("::")),
- ["BreakStat"] = ha("Break", ga("break")),
- ["ContinueStat"] = ha("Continue", ga("continue")),
- ["GoToStat"] = ha("Goto", ga("goto") * da(k("Name"), "Name")),
- ["RetStat"] = ha("Return", ga("return") * (k("Expr") * (fa(",") * k("Expr")) ^ 0) ^ (-1) * fa(";") ^ (-1)),
- ["ExprStat"] = r((k(c) * (o(function()
- local za = {...}
- local Aa = za[#za]
- table.remove(za)
-
- for Ba, ya in ipairs(za) do
- if ya.tag == "Id" then
- orya.tag"Index"
- else
- za[Ba] = ya
-
- return false
- end
- end
+ local function Xa(Ea, Va)
+ local Ya, P = Na(Ea, Va[1])
+ if not Ya then return Ya, P end
- za.tag = "VarList"
- za.pos = za[1].pos
+ return true
+ end
- return true, {
- ["tag"] = "Set",
- ["pos"] = za.pos,
- [1] = za,
- [2] = Aa
- }
- end) * k("Assignment"))) + (k(c) * (o(function(R)
- if R.tag == "Call" then
- orR.tag"Invoke"
+ local function Ya(Ea, Za)
+ for ab, ya in ipairs(Za) do
+ local ia = ya.tag
+
+ if ia == "Pair" then
+ local bb, P = Na(Ea, ya[1])
+ if not bb then return bb, P end
+ bb, P, bb, P = Na(Ea, ya[2])
+ if not bb then return bb, P end
else
- return true, R
+ local bb, P = Na(Ea, ya)
+ if not bb then return bb, P end
end
+ end
- return false
- end))), function(R, S, za, Aa, ...) return Aa(za, ...) end),
- ["Assignment"] = ((fa(",") * k(c)) ^ 1) ^ (-1) * fa("=") * k("ExpList"),
- ["Stat"] = k("IfStat") + k("WhileStat") + k("DoStat") + k("ForStat") + k("RepeatStat") + k("FuncStat") + k("LocalStat") + k("LabelStat") + k("BreakStat") + k("GoToStat") + k("ExprStat") + k("ContinueStat"),
- ["Space"] = y ^ 1,
- ["Equals"] = i("=") ^ 0,
- ["Open"] = "[" * q(k("Equals"), "init") * "[" * i("\n") ^ (-1),
- ["Close"] = "]" * l(k("Equals")) * "]",
- ["CloseEQ"] = r(k("Close") * n("init"), function(R, S, ra, Ba) return ra == Ba end),
- ["LongString"] = k("Open") * l((i(1) - k("CloseEQ")) ^ 0) * k("Close") / function(R, Ca) return R end,
- ["Comment"] = i("--") * k("LongString") / function() return end + i("--") * (i(1) - i("\n")) ^ 0 + i("//") * (i(1) - i("\n")) ^ 0 + l(L) / function() return end,
- ["Skip"] = (k("Space") + k("Comment")) ^ 0,
- ["idStart"] = u + i("_"),
- ["idRest"] = w + i("_"),
- ["Keywords"] = i("and") + "break" + "do" + "elseif" + "else" + "end" + "false" + "for" + d + "goto" + "if" + "in" + "local" + "nil" + "not" + "or" + "repeat" + "return" + "then" + "true" + "until" + "while" + "continue",
- ["Reserved"] = k("Keywords") * -k("idRest"),
- ["Identifier"] = k("idStart") * k("idRest") ^ 0,
- ["Name"] = -k("Reserved") * l(k("Identifier")) * -k("idRest"),
- ["Hex"] = (i("0x") + i("0X")) * x ^ 1,
- ["Expo"] = j("eE") * j("+-") ^ (-1) * v ^ 1,
- ["Float"] = (((v ^ 1 * i(".") * v ^ 0) + (i(".") * v ^ 1)) * k("Expo") ^ (-1)) + (v ^ 1 * k("Expo")),
- ["Int"] = v ^ 1,
- ["Number"] = l(k("Hex") + k("Float") + k("Int")) / function(Y) return tonumber(Y) end,
- ["ShortString"] = i([["]]) * l(((i("\\") * i(1)) + (i(1) - i([["]]))) ^ 0) * i([["]]) + i("'") * l(((i("\\") * i(1)) + (i(1) - i("'"))) ^ 0) * i("'"),
- [a] = k("LongString") + (k("ShortString") / function(R) return R end),
- ["OrOp"] = ga("or") / "or" + fa("||") / "or",
- ["AndOp"] = ga("and") / "and" + fa("&&") / "and",
- ["RelOp"] = fa("~=") / "ne" + fa("==") / "eq" + fa("<=") / "le" + fa(">=") / "ge" + fa("<") / "lt" + fa(">") / "gt" + fa("!=") / "ne",
- ["BOrOp"] = fa("|") / "bor",
- ["BXorOp"] = fa("~") / "bxor",
- ["BAndOp"] = fa("&") / "band",
- ["ShiftOp"] = fa("<<") / "shl" + fa(">>") / "shr",
- ["ConOp"] = fa("..") / "concat",
- ["AddOp"] = fa("+") / "add" + fa("-") / "sub",
- ["MulOp"] = fa("*") / "mul" + fa("/") / "div" + fa("%") / "mod",
- ["UnOp"] = ga("not") / "not" + fa("-") / "unm" + fa("#") / "len" + fa("~") / "bnot" + fa("!") / "not",
- ["PowOp"] = fa("^") / "pow",
- ["Shebang"] = i("#") * (i(1) - i("\n")) ^ 0 * i("\n"),
- ["OneWord"] = k("Name") + k("Number") + k(a) + k("Reserved") + i("...") + i(1)
- }
+ return true
+ end
- local function Da(Ea, h, Fa)
- local Ga = Fa[1]
+ local function ab(Ea, Va)
+ if not Ea.Ea.fscope.is_vararg then
+ local P = e
- for R = h, 0, -1 do
- if Ea[R].label[Ga] then return true end
- end
+ return nil, M(Ea.errorinfo, Va.pos, P)
+ end
+
+ return true
+ end
- return false
+ local function bb(Ea, cb)
+ local db, P = Na(Ea, cb[1])
+ if not db then return db, P end
+ forS = 2
+
+ do
+ db, P, db, P = Na(Ea, cb[S])
+ if not db then return db, P end
end
- local function Ga(Ea, Ha, O)
- local h = Ea.scope
- local Ia = Ea[h].label[Ha]
+ return true
+ end
- if not Ia then
- Ea[h].label[Ha] = {
- ["name"] = Ha,
- ["pos"] = O
- }
+ local function db(Ea, eb)
+ local fb, P = Na(Ea, eb[1])
+ if not fb then return fb, P end
+ forS = 3
- return true
- else
- local P = "label '%s' already defined at line %d"
- local Ja = z(Ea.errorinfo.subject, Ia.pos)
- P = string.format(P, Ha, Ja)
+ do
+ fb, P, fb, P = Na(Ea, eb[S])
+ if not fb then return fb, P end
+ end
- return nil, M(Ea.errorinfo, O, P)
- end
+ return true
+ end
+
+ local function fb(Ea, Fa)
+ local gb, P = Ra(Ea, Fa[1])
+ if not gb then return gb, P end
+ gb, P, gb, P = Qa(Ea, Fa[2])
+ if not gb then return gb, P end
+
+ return true
+ end
+
+ local function gb(Ea, Fa)
+ if not G(Ea) then
+ local P = "<break> not inside a loop"
+
+ return nil, M(Ea.errorinfo, Fa.pos, P)
end
- local function Ia(Ea, Fa)
- local h = Ea.scope
- table.insert(Ea[h].goto, Fa)
+ return true
+ end
+
+ local function hb(Ea, Fa)
+ if not G(Ea) then
+ local P = "<continue> not inside a loop"
- return true
+ return nil, M(Ea.errorinfo, Fa.pos, P)
end
- local function Ja(Ea)
- for R = Ea.maxscope, 0, -1 do
- for Ka, ya in ipairs(Ea[R].goto) do
- ifnot"someString"
- Da(Ea, R, ya)
- local P = "no visible label '%s' for <goto>"
- P = string.format(P, ya[1])
+ return true
+ end
- return nil, M(Ea.errorinfo, ya.pos, P)
- end
- end
+ local function ib(Ea, Fa)
+ E(Ea)
+ A(Ea)
+ local jb, P = Qa(Ea, Fa[2])
+ if not jb then return jb, P end
+ jb, P, jb, P = Pa(Ea, Fa[3])
+ if not jb then return jb, P end
+ B(Ea)
+ F(Ea)
+
+ return true
+ end
+
+ local function jb(Ea, Fa)
+ local kb, P
+ E(Ea)
+ A(Ea)
+ kb, P, kb, P = Na(Ea, Fa[2])
+ if not kb then return kb, P end
+ kb, P, kb, P = Na(Ea, Fa[3])
+ if not kb then return kb, P end
+
+ if Fa[5] then
+ kb, P, kb, P = Na(Ea, Fa[4])
+ if not kb then return kb, P end
+ kb, P, kb, P = Pa(Ea, Fa[5])
+ if not kb then return kb, P end
+ else
+ kb, P, kb, P = Pa(Ea, Fa[4])
+ if not kb then return kb, P end
end
- return true, Ka(Ea, La), Ea.Ea.fscope.is_vararg{
- someVariable = La,
- Na,
- Oa or Pa,
- Qa,
- Ra,
- Sa{
- Sa = function(Ea, Ta)
- local Ua = #Ta
- local La = false
-
- if 0 < Ua and Ta[Ua].tag == "Dots" then
- La = true
- end
-
- Ka(Ea, La)
-
- return true
- end,
- Ua(Ea, Va)
- }(Ea)
- }(Ea), P, Sa(Ea, Va[1]), not Wa, P, P, Wa, P, Pa(Ea, Va[2]), not Wa, P, (Ea), (Ea), true, Wa(Ea, Va), P, Na(Ea, Va[2]), not Xa, Xa, P, Va[3], P, Xa, P, Na(Ea, Va[3]), not Xa, Xa, P, true, Xa(Ea, Va), P, Na(Ea, Va[1]), not Ya, Ya, P, true, Ya(Ea, Za), ya, (Za){
- ia = ya.tag,
- ia == "Pair",
- P = Na(Ea, ya[1]),
- not bb,
- P or bb,
- P,
- bb,
- P = Na(Ea, ya[2]),
- not bb,
- bb,
- P or bb,
- P = Na(Ea, ya),
- not bb, bb, P or true, ab(Ea, Va)
- }, not Ea.Ea.fscope.is_vararg{
- P = e
- }, M(Ea.errorinfo, Va.pos, P), true, bb(Ea, cb), P, Na(Ea, cb[1]), not db, db, P{
- S = 2,
- #cb
- }, P, db, P, Na(Ea, cb[S]), not db, db, P, true, db(Ea, eb), P, Na(Ea, eb[1]), not fb, fb, P{
- S = 3,
- #eb
- }, P, fb, P, Na(Ea, eb[S]), not fb, fb, P, true, fb(Ea, Fa), P, Ra(Ea, Fa[1]), not gb, P, P, gb, P, Qa(Ea, Fa[2]), not gb, gb, P, true, gb(Ea, Fa), ifnot, (Ea), P"<break> not inside a loop", M(Ea.errorinfo, Fa.pos, P), true, hb(Ea, Fa), ifnot, (Ea), P"<continue> not inside a loop", M(Ea.errorinfo, Fa.pos, P), true, ib(Ea, Fa), (Ea), (Ea), P, Qa(Ea, Fa[2]), not jb, P, P, jb, P, Pa(Ea, Fa[3]), not jb, P, (Ea), (Ea), true, jb(Ea, Fa), P, (Ea), (Ea), P, kb, P, Na(Ea, Fa[2]), not kb, P, P, kb, P, Na(Ea, Fa[3]), not kb, kb, P, Fa[5], P, kb, P, Na(Ea, Fa[4]), not kb, P, P, kb, P, Pa(Ea, Fa[5]), not kb, kb, P, P, kb, P, Pa(Ea, Fa[4]), not kb, kb, P, (Ea), (Ea), true, kb(Ea, Fa), P, Ia(Ea, Fa), not lb, lb, P, true, lb(Ea, Fa){
- mb = #Fa
- } % 2 == 0, mb, 2, P, Na(Ea, Fa[S]), not nb, P, P, nb, P, Pa(Ea, Fa[S + 1]), not nb, nb, P, mb - 1, 2, P, Na(Ea, Fa[S]), not nb, P, P, nb, P, Pa(Ea, Fa[S + 1]), not nb, nb, P, P, Pa(Ea, Fa[mb]), not nb, nb, P, true, mb(Ea, Fa), P, Ga(Ea, Fa[1], Fa.pos), not nb, nb, P, true, nb(Ea, Fa), P, Qa(Ea, Fa[2]), not ob, ob, P, true, ob(Ea, Fa), P, Na(Ea, Fa[2][1]), not pb, pb, P, true, pb(Ea, Fa), (Ea), P, Pa(Ea, Fa[1]), not qb, P, P, qb, P, Na(Ea, Fa[2]), not qb, P, (Ea), true, qb(Ea, Fa), P, Qa(Ea, Fa), not rb, rb, P, true, rb(Ea, Fa), (Ea), P, Na(Ea, Fa[1]), not sb, P, P, sb, P, Pa(Ea, Fa[2]), not sb, P, (Ea), true, function(Ea, sb)
- local ia = sb.tag
-
- if ia == "Id" then
- return true
- elseif ia == "Index" then
- thenelse"expecting a variable, but got a "
- ia()
- end
- end, function(Ea, tb)
- for ub, ya in ipairs(tb) do
- local vb, P = Oa(Ea, ya)
- if not vb then return vb, P end
- end
+ B(Ea)
+ F(Ea)
- return true
- end, function(Ea, Va)
- local ia = Va.tag
-
- if ia == "Nil" then
- oria"True"
- oria"False"
- oria"Number"
- oria"someString"
-
- return true
- elseif ia == "Dots" then
- elseif ia == "Function" then
- elseif ia == "Table" then
- elseif ia == "Op" then
- elseif ia == "Paren" then
- elseif ia == "Call" then
- elseif ia == "Invoke" then
- elseif ia == "Id" then
- oria"Index"
- thenelse"expecting an expression, but got a "
- ia()
+ return true
+ end
+
+ local function kb(Ea, Fa)
+ local lb, P = Ia(Ea, Fa)
+ if not lb then return lb, P end
+
+ return true
+ end
+
+ local function lb(Ea, Fa)
+ local mb = #Fa
+
+ if mb % 2 == 0 then
+ forS = 1
+
+ do
+ local nb, P = Na(Ea, Fa[S])
+ if not nb then return nb, P end
+ nb, P, nb, P = Pa(Ea, Fa[S + 1])
+ if not nb then return nb, P end
end
- end, function(Ea, ub)
- for vb, ya in ipairs(ub) do
- local wb, P = Na(Ea, ya)
- if not wb then return wb, P end
+ else
+ forS = 1
+
+ do
+ local nb, P = Na(Ea, Fa[S])
+ if not nb then return nb, P end
+ nb, P, nb, P = Pa(Ea, Fa[S + 1])
+ if not nb then return nb, P end
end
+ local nb, P = Pa(Ea, Fa[mb])
+ if not nb then return nb, P end
+ end
+
+ return true
+ end
+
+ local function mb(Ea, Fa)
+ local nb, P = Ga(Ea, Fa[1], Fa.pos)
+ if not nb then return nb, P end
+
+ return true
+ end
+
+ local function nb(Ea, Fa)
+ local ob, P = Qa(Ea, Fa[2])
+ if not ob then return ob, P end
+
+ return true
+ end
+
+ local function ob(Ea, Fa)
+ local pb, P = Na(Ea, Fa[2][1])
+ if not pb then return pb, P end
+
+ return true
+ end
+
+ local function pb(Ea, Fa)
+ E(Ea)
+ local qb, P = Pa(Ea, Fa[1])
+ if not qb then return qb, P end
+ qb, P, qb, P = Na(Ea, Fa[2])
+ if not qb then return qb, P end
+ F(Ea)
+
+ return true
+ end
+
+ local function qb(Ea, Fa)
+ local rb, P = Qa(Ea, Fa)
+ if not rb then return rb, P end
+
+ return true
+ end
+
+ local function rb(Ea, Fa)
+ E(Ea)
+ local sb, P = Na(Ea, Fa[1])
+ if not sb then return sb, P end
+ sb, P, sb, P = Pa(Ea, Fa[2])
+ if not sb then return sb, P end
+ F(Ea)
+
+ return true
+ end
+
+ Oa = function(Ea, sb)
+ local ia = sb.tag
+
+ if ia == "Id" then
return true
- end, function(Ea, Fa)
- local ia = Fa.tag
-
- if ia == "Do" then
- return Pa(Ea, Fa)
- elseif ia == "Set" then
- elseif ia == "While" then
- elseif ia == "Repeat" then
- elseif ia == "If" then
- elseif ia == "Fornum" then
- elseif ia == "Forin" then
- elseif ia == "Local" then
- elseif ia == "Localrec" then
- elseif ia == "Goto" then
- elseif ia == "Label" then
- elseif ia == "Return" then
- elseif ia == "Break" then
- elseif ia == "Continue" then
- elseif ia == "Call" then
- elseif ia == "Invoke" then
- thenelse"expecting a statement, but got a "
- ia()
- end
- end, function(Ea, vb)
- local wb = {}
- A(Ea)
+ elseif ia == "Index" then
+ thenelse"expecting a variable, but got a "
+ ia()
+ end
+ end
- for xb, ya in ipairs(vb) do
- local yb, P = Ma(Ea, ya)
- if not yb then return yb, P end
- end
+ Ra = function(Ea, tb)
+ for ub, ya in ipairs(tb) do
+ local vb, P = Oa(Ea, ya)
+ if not vb then return vb, P end
+ end
+
+ return true
+ end
- B(Ea)
+ Na = function(Ea, Va)
+ local ia = Va.tag
+
+ if ia == "Nil" then
+ oria"True"
+ oria"False"
+ oria"Number"
+ oria"someString"
return true
- end, wb(xb, N), assert(type(xb) == "table"), assert(type(N) == "table"), Ea, {
+ elseif ia == "Dots" then
+ elseif ia == "Function" then
+ elseif ia == "Table" then
+ elseif ia == "Op" then
+ elseif ia == "Paren" then
+ elseif ia == "Call" then
+ elseif ia == "Invoke" then
+ elseif ia == "Id" then
+ oria"Index"
+ thenelse"expecting an expression, but got a "
+ ia()
+ end
+ end
+
+ Qa = function(Ea, ub)
+ for vb, ya in ipairs(ub) do
+ local wb, P = Na(Ea, ya)
+ if not wb then return wb, P end
+ end
+
+ return true
+ end
+
+ Ma = function(Ea, Fa)
+ local ia = Fa.tag
+
+ if ia == "Do" then
+ return Pa(Ea, Fa)
+ elseif ia == "Set" then
+ elseif ia == "While" then
+ elseif ia == "Repeat" then
+ elseif ia == "If" then
+ elseif ia == "Fornum" then
+ elseif ia == "Forin" then
+ elseif ia == "Local" then
+ elseif ia == "Localrec" then
+ elseif ia == "Goto" then
+ elseif ia == "Label" then
+ elseif ia == "Return" then
+ elseif ia == "Break" then
+ elseif ia == "Continue" then
+ elseif ia == "Call" then
+ elseif ia == "Invoke" then
+ thenelse"expecting a statement, but got a "
+ ia()
+ end
+ end
+
+ Pa = function(Ea, vb)
+ local wb = {}
+ A(Ea)
+
+ for xb, ya in ipairs(vb) do
+ local yb, P = Ma(Ea, ya)
+ if not yb then return yb, P end
+ end
+
+ B(Ea)
+
+ return true
+ end
+
+ local function wb(xb, N)
+ assert(type(xb) == "table")
+ assert(type(N) == "table")
+
+ local Ea = {
[b] = N,
[d] = {}
- }, (Ea), Ka(Ea, true), P, Pa(Ea, xb), not yb, P, (Ea), P, yb, P, (Ea), not yb, yb, P, f.parse, function(yb, zb)
- local N = {
- ["subject"] = yb,
- ["filename"] = zb
- }
+ }
- g.setmaxstack(1000)
- local xb, Ab = g.match(va, yb, nil, N)
- if not xb then return xb, Ab end
+ C(Ea)
+ Ka(Ea, true)
+ local yb, P = Pa(Ea, xb)
+ if not yb then return yb, P end
+ D(Ea)
+ yb, P, yb, P = Ja(Ea)
+ if not yb then return yb, P end
- return wb(xb, N)
- end
+ return xb
+ end
+
+ f.parse = function(yb, zb)
+ local N = {
+ ["subject"] = yb,
+ ["filename"] = zb
+ }
+
+ g.setmaxstack(1000)
+ local xb, Ab = g.match(va, yb, nil, N)
+ if not xb then return xb, Ab end
+
+ return wb(xb, N)
+ end
+
+ return f