local a = function() local a = {} local b = require("lpeg") local c = function() local c = {} c.lineno = function(d, e) if e == 1 then return 1, 1 end local g, h = 0, "" d = d["sub"](d, 1, e) .. "\\n" for j in d["gmatch"](d, "[^\\n]*[\\n]") do g = g + 1 h = j end local j = h["len"](h, nil) - 1 return g, not j == 0 and j or 1 end c.new_scope = function(g) if not g.scope then g.scope = 0 else g.scope = g.scope + 1 end local c = g.scope g.maxscope = c g[c] = {} g[c].label = {} g[c].someVariable{} g[c].goto = {} end c.begin_scope = function(g) g.scope = g.scope + 1 end c.end_scope = function(g) g.scope = g.scope - 1 end c.new_function = function(g) if not g.fscope then g.fscope = 0 else g.fscope = g.fscope + 1 end local h = g.fscope g.h = {} end c.begin_function = function(g) g.fscope = g.fscope + 1 end c.end_function = function(g) g.fscope = g.fscope - 1 end c.begin_loop = function(g) if not g.loop then g.loop = 1 else g.loop = g.loop + 1 end end c.end_loop = function(g) g.loop = g.loop - 1 end c.insideloop = function(g) return g.loop and 0 < g.loop end return c end c = c() b.locale(b) local d, e, g = b.P, b.S, b.V local h, j, k, l = b.C, b.Carg, b.Cb, b.Cc local m, n, o, p, q = b.Cf, b.Cg, b.Cmt, b.Cp, b.Ct local r, s, t = b.alpha, b.digit, b.alnum local u = b.xdigit local v = b.space local w = c.lineno local x, y = c.new_scope, c.end_scope local z, A = c.new_function, c.end_function local B, C = c.begin_loop, c.end_loop local D = c.insideloop local E = b.P("/*") local F = b.P("*/") local G = (1 - E) ^ 0 local H = (1 - F) ^ 0 local I = E * H * F local function J(K, L, M) local N, O = w(K.subject, L) local P = "%s:%d:%d: syntax error, %s" return string.format(P, K.filename, N, O, M) end local function N(O, P, Q) return Q.ffp or P, Q end local function R() return o(j(1), N) * (h(g("OneWord")) + l("EOF")) / function(Q, S) Q.unexpected = S return Q end end local function S() return R() / function(Q) local T = Q.ffp or 1 local M = "unexpected \\'%s\\', expecting %s" M = string.format(M, Q.unexpected, Q.expected) return nil, J(Q, T, M) end end local function T() return S() end local function U(O, P, Q, V) if not Q.ffp or Q.ffp < P then Q.ffp = P Q.list = {} Q.list[V] = V Q.expected = "\\'" .. V .. "\\'" elseif P == Q.ffp then if not Q.list[V] then Q.list[V] = V Q.expected = "\\'" .. V .. "\\', " .. Q.expected end end return false end local function W(X) return o(j(1) * l(X), U) end local function Y(Z, X) return Z * g("Skip") + W(X) * d(false) end local function aa(ba) return Y(d(ba), ba) end local function ca(ba) return Y(d(ba) * -g("idRest"), ba) end local function da(ea, Z) return q(n(p(), "pos") * n(l(ea), "tag") * Z) end local function fa(ga, ha) return { ["tag"] = "Op", ["pos"] = ha.pos, [1] = ga, [2] = ha } end local function ia(ja, ga, ka) if not ga then return ja elseif ga == "add" or ga == "sub" or ga == "mul" or ga == "div" or ga == "idiv" or ga == "mod" or ga == "pow" or ga == "concat" or ga == "band" or ga == "bor" or ga == "bxor" or ga == "shl" or ga == "shr" or ga == "eq" or ga == "lt" or ga == "le" or ga == "and" or ga == "or" then return { ["tag"] = "Op", ["pos"] = ja.pos, [1] = ga, [2] = ja, [3] = ka } elseif ga == "ne" then return fa("not", { ["tag"] = "Op", ["pos"] = ja.pos, [1] = "eq", [2] = ja, [3] = ka }) elseif ga == "gt" then return { ["tag"] = "Op", ["pos"] = ja.pos, [1] = "lt", [2] = ka, [3] = ja } elseif ga == "ge" then return { ["tag"] = "Op", ["pos"] = ja.pos, [1] = "le", [2] = ka, [3] = ja } end end local function la(Z, ma, na) return m(Z * n(ma * Z) ^ 0, ia) + na end local function oa(Z, ma) return m(Z * n(ma * Z) ^ 0, ia) end local function pa(Z, ma, ea) return da(ea, (Z * (ma * Z) ^ 0) ^ nil - 1) end local function qa(Z, ma, ea) return da(ea, Z * (ma * Z) ^ 0) end local function ra(ba) ba = string.gsub(ba, "\\\\\\a", "\\a") ba = string.gsub(ba, "\\\\\\b", "\\b") ba = string.gsub(ba, "\\\\\\f", "\\f") ba = string.gsub(ba, "\\n", "\\n") ba = string.gsub(ba, "\\n", "\\r") ba = string.gsub(ba, "\\\\\\t", "\\t") ba = string.gsub(ba, "\\\\\\v", "\\v") ba = string.gsub(ba, "\\\\\\n", "\\n") ba = string.gsub(ba, "\\\\\\n", "\\n") ba = string.gsub(ba, "\\\\\\'", "\\'") ba = string.gsub(ba, "\\\\\\\"", "\\\"") ba = string.gsub(ba, "\\\\\\\\", "\\\\") return ba end local sa = { g("Lua"), ["Lua"] = g("Shebang") ^ nil - 1 * g("Skip") * g("Chunk") * -1 + T(), ["Chunk"] = g("Block"), ["StatList"] = (aa(";") + g("Stat")) ^ 0, ["Var"] = g("Id"), ["Id"] = da("Id", Y(g("Name"), "Name")), ["FunctionDef"] = ca("function") * g("FuncBody"), ["FieldSep"] = aa(",") + aa(";"), ["Field"] = da("Pair", (aa("[") * g("Expr") * aa("]") * aa("=") * g("Expr")) + (da("String", Y(g("Name"), "Name")) * aa("=") * g("Expr"))) + g("Expr"), ["FieldList"] = (g("Field") * (g("FieldSep") * g("Field")) ^ 0 * g("FieldSep") ^ nil - 1) ^ nil - 1, ["Constructor"] = da("Table", aa("{") * g("FieldList") * aa("}")), ["NameList"] = qa(g("Id"), aa(","), "NameList"), ["ExpList"] = qa(g("Expr"), aa(","), "ExpList"), ["FuncArgs"] = aa("(") * (g("Expr") * (aa(",") * g("Expr")) ^ 0) ^ nil - 1 * aa(")") + g("Constructor") + da("String", Y(g("String"), "String")), ["Expr"] = g("SubExpr_1"), ["SubExpr_1"] = oa(g("SubExpr_2"), g("OrOp")), ["SubExpr_2"] = oa(g("SubExpr_3"), g("AndOp")), ["SubExpr_3"] = oa(g("SubExpr_4"), g("RelOp")), ["SubExpr_4"] = oa(g("SubExpr_5"), g("BOrOp")), ["SubExpr_5"] = oa(g("SubExpr_6"), g("BXorOp")), ["SubExpr_6"] = oa(g("SubExpr_7"), g("BAndOp")), ["SubExpr_7"] = oa(g("SubExpr_8"), g("ShiftOp")), ["SubExpr_8"] = g("SubExpr_9") * g("ConOp") * g("SubExpr_8") / ia + g("SubExpr_9"), ["SubExpr_9"] = oa(g("SubExpr_10"), g("AddOp")), ["SubExpr_10"] = oa(g("SubExpr_11"), g("MulOp")), ["SubExpr_11"] = g("UnOp") * g("SubExpr_11") / fa + g("SubExpr_12"), ["SubExpr_12"] = g("SimpleExp") * (g("PowOp") * g("SubExpr_11")) ^ nil - 1 / ia, ["SimpleExp"] = da("Number", Y(g("Number"), "Number")) + da("String", Y(g("String"), "String")) + da("Nil", ca("nil")) + da("False", ca("false")) + da("True", ca("true")) + da("Dots", aa("...")) + g("FunctionDef") + g("Constructor") + g("SuffixedExp"), ["SuffixedExp"] = m(g("PrimaryExp") * (da("DotIndex", aa(".") * da("String", Y(g("Name"), "Name"))) + da("ArrayIndex", aa("[") * g("Expr") * aa("]")) + da("Invoke", n(aa(":") * da("String", Y(g("Name"), "Name")) * g("FuncArgs"))) + da("Call", g("FuncArgs"))) ^ 0, function(ta, ua) if ua then if ua.tag == "Call" or ua.tag == "Invoke" then local Q = { ["tag"] = ua.tag, ["pos"] = ta.pos, [1] = ta } for va, wa in ipairs(ua) do table.insert(Q, wa) end return Q else return { ["tag"] = "Index", ["pos"] = ta.pos, [1] = ta, [2] = ua[1] } end end return ta end), ["PrimaryExp"] = g("Var") + da("Paren", aa("(") * g("Expr") * aa(")")), ["Block"] = da("Block", g("StatList") * g("RetStat") ^ nil - 1), ["IfStat"] = da("If", ca("if") * g("Expr") * ca("then") * g("Block") * (ca("elseif") * g("Expr") * ca("then") * g("Block")) ^ 0 * (ca("else") * g("Block")) ^ nil - 1 * ca("end")), ["WhileStat"] = da("While", ca("while") * g("Expr") * ca("do") * g("Block") * ca("end")), ["DoStat"] = ca("do") * g("Block") * ca("end") / function(Q) Q.tag = "Do" return Q end, ["ForBody"] = ca("do") * g("Block"), ["ForNum"] = da("Fornum", g("Id") * aa("=") * g("Expr") * aa(",") * g("Expr") * (aa(",") * g("Expr")) ^ nil - 1 * g("ForBody")), ["ForGen"] = da("Forin", g("NameList") * ca("in") * g("ExpList") * g("ForBody")), ["ForStat"] = ca("for") * (g("ForNum") + g("ForGen")) * ca("end"), ["RepeatStat"] = da("Repeat", ca("repeat") * g("Block") * ca("until") * g("Expr")), ["FuncName"] = m(g("Id") * (aa(".") * da("String", Y(g("Name"), "Name"))) ^ 0, function(ta, ua) if ua then return { ["tag"] = "Index", ["pos"] = ta.pos, [1] = ta, [2] = ua } end return ta end) * (aa(":") * da("String", Y(g("Name"), "Name"))) ^ nil - 1 / function(ta, ua) if ua then return { ["tag"] = "Index", ["pos"] = ta.pos, ["is_method"] = true, [1] = ta, [2] = ua } end return ta end, ["ParList"] = g("NameList") * (aa(",") * aa("...") * da("Dots", p())) ^ nil - 1 / function(Q, va) if va then table.insert(Q, va) end return Q end + aa("...") * da("Dots", p()) / function(va) return {va} end + d(true) / function() return {} end, ["FuncBody"] = da("Function", aa("(") * g("ParList") * aa(")") * g("Block") * ca("end")), ["FuncStat"] = da("Set", ca("function") * g("FuncName") * g("FuncBody")) / function(Q) if Q[1].is_method then table.insert(Q[2][1], 1, { ["tag"] = "Id", [1] = "self" }) end Q[1] = {Q[1]} Q[2] = {Q[2]} return Q end, ["LocalFunc"] = da("Localrec", ca("function") * g("Id") * g("FuncBody")) / function(Q) Q[1] = {Q[1]} Q[2] = {Q[2]} return Q end, ["LocalAssign"] = da("Local", g("NameList") * ((aa("=") * g("ExpList")) + q(l()))), ["LocalStat"] = ca("local") * (g("LocalFunc") + g("LocalAssign")), ["LabelStat"] = da("Label", aa("::") * Y(g("Name"), "Name") * aa("::")), ["BreakStat"] = da("Break", ca("break")), ["ContinueStat"] = da("Continue", ca("continue")), ["GoToStat"] = da("Goto", ca("goto") * Y(g("Name"), "Name")), ["RetStat"] = da("Return", ca("return") * (g("Expr") * (aa(",") * g("Expr")) ^ 0) ^ nil - 1 * aa(";") ^ nil - 1), ["ExprStat"] = o((g("SuffixedExp") * (l(function() local wa = {...} local xa = wa[#wa] table.remove(wa) for ya, va in ipairs(wa) do if va.tag == "Id" or va.tag == "Index" then wa[ya] = va else return false end end wa.tag = "VarList" wa.pos = wa[1].pos return true, { ["tag"] = "Set", ["pos"] = wa.pos, [1] = wa, [2] = xa } end) * g("Assignment"))) + (g("SuffixedExp") * (l(function(O) if O.tag == "Call" or O.tag == "Invoke" then return true, O end return false end))), function(O, P, wa, xa, ...) return xa(wa, ...) end), ["Assignment"] = ((aa(",") * g("SuffixedExp")) ^ 1) ^ nil - 1 * aa("=") * g("ExpList"), ["Stat"] = g("IfStat") + g("WhileStat") + g("DoStat") + g("ForStat") + g("RepeatStat") + g("FuncStat") + g("LocalStat") + g("LabelStat") + g("BreakStat") + g("GoToStat") + g("ExprStat") + g("ContinueStat"), ["Space"] = v ^ 1, ["Equals"] = d("=") ^ 0, ["Open"] = "[" * n(g("Equals"), "init") * "[" * d("\\n") ^ nil - 1, ["Close"] = "]" * h(g("Equals")) * "]", ["CloseEQ"] = o(g("Close") * k("init"), function(O, P, na, ya) return na == ya end), ["LongString"] = g("Open") * h((d(1) - g("CloseEQ")) ^ 0) * g("Close") / function(O, za) return O end, ["Comment"] = d("--") * g("LongString") / function() return end + d("--") * (d(1) - d("\\n")) ^ 0 + d("//") * (d(1) - d("\\n")) ^ 0 + h(I) / function() return end, ["Skip"] = (g("Space") + g("Comment")) ^ 0, ["idStart"] = r + d("_"), ["idRest"] = t + d("_"), ["Keywords"] = d("and") + "break" + "do" + "elseif" + "else" + "end" + "false" + "for" + "function" + "goto" + "if" + "in" + "local" + "nil" + "not" + "or" + "repeat" + "return" + "then" + "true" + "until" + "while" + "continue", ["Reserved"] = g("Keywords") * -g("idRest"), ["Identifier"] = g("idStart") * g("idRest") ^ 0, ["Name"] = -g("Reserved") * h(g("Identifier")) * -g("idRest"), ["Hex"] = (d("0x") + d("0X")) * u ^ 1, ["Expo"] = e("eE") * e("+-") ^ nil - 1 * s ^ 1, ["Float"] = (((s ^ 1 * d(".") * s ^ 0) + (d(".") * s ^ 1)) * g("Expo") ^ nil - 1) + (s ^ 1 * g("Expo")), ["Int"] = s ^ 1, ["Number"] = h(g("Hex") + g("Float") + g("Int")) / function(V) return tonumber(V) end, ["ShortString"] = d("\\\"") * h(((d("\\\\") * d(1)) + (d(1) - d("\\\""))) ^ 0) * d("\\\"") + d("\\'") * h(((d("\\\\") * d(1)) + (d(1) - d("\\'"))) ^ 0) * d("\\'"), ["String"] = g("LongString") + (g("ShortString") / function(O) return ra(O) end), ["OrOp"] = ca("or") / "or" + aa("||") / "or", ["AndOp"] = ca("and") / "and" + aa("&&") / "and", ["RelOp"] = aa("~=") / "ne" + aa("==") / "eq" + aa("<=") / "le" + aa(">=") / "ge" + aa("<") / "lt" + aa(">") / "gt" + aa("!=") / "ne", ["BOrOp"] = aa("|") / "bor", ["BXorOp"] = aa("~") / "bxor", ["BAndOp"] = aa("&") / "band", ["ShiftOp"] = aa("<<") / "shl" + aa(">>") / "shr", ["ConOp"] = aa("..") / "concat", ["AddOp"] = aa("+") / "add" + aa("-") / "sub", ["MulOp"] = aa("*") / "mul" + aa("/") / "div" + aa("%") / "mod", ["UnOp"] = ca("not") / "not" + aa("-") / "unm" + aa("#") / "len" + aa("~") / "bnot" + aa("!") / "not", ["PowOp"] = aa("^") / "pow", ["Shebang"] = d("#") * (d(1) - d("\\n")) ^ 0 * d("\\n"), ["OneWord"] = g("Name") + g("Number") + g("String") + g("Reserved") + d("...") + d(1) } local function Aa(Ba, c, Ca) local Da = Ca[1] for O = c, 0, -1 do if Ba[O].label[Da] then return true end end return false end local function Da(Ba, Ea, L) local c = Ba.scope local Fa = Ba[c].label[Ea] if not Fa then Ba[c].label[Ea] = { ["name"] = Ea, ["pos"] = L } return true else local M = "label \\'%s\\' already defined at line %d" local Ga = w(Ba.errorinfo.subject, Fa.pos) M = string.format(M, Ea, Ga) return nil, J(Ba.errorinfo, L, M) end end local function Fa(Ba, Ca) local c = Ba.scope table.insert(Ba[c].goto, Ca) return true end local function Ga(Ba) for O = Ba.maxscope, 0, -1 do for Ha, va in ipairs(Ba[O].goto) do if not Aa(Ba, O, va) then local M = "no visible label \\'%s\\' for " M = string.format(M, va[1]) return nil, J(Ba.errorinfo, va.pos, M) end end end return true end local function Ha(Ba, Ia) Ba.Ba.fscope.is_vararg = Ia end local Ja, Ka, Lalocal Ma, Na, Oa, PaPa = function(Ba, Qa) local Ra = #Qa local Ia = false if 0 < Ra and Qa[Ra].tag == "Dots" then Ia = true end Ha(Ba, Ia) return true end local function Ra(Ba, Sa) z(Ba) x(Ba) local Ta, M = Pa(Ba, Sa[1]) if not Ta then return Ta, M end Ta, M, Ta, M = Ma(Ba, Sa[2]) if not Ta then return Ta, M end y(Ba) A(Ba) return true end local function Ta(Ba, Sa) local Ua, M = Ka(Ba, Sa[2]) if not Ua then return Ua, M end if Sa[3] then Ua, M, Ua, M = Ka(Ba, Sa[3]) if not Ua then return Ua, M end end return true end local function Ua(Ba, Sa) local Va, M = Ka(Ba, Sa[1]) if not Va then return Va, M end return true end local function Va(Ba, Wa) for Xa, va in ipairs(Wa) do local ea = va.tag if ea == "Pair" then local Ya, M = Ka(Ba, va[1]) if not Ya then return Ya, M end Ya, M, Ya, M = Ka(Ba, va[2]) if not Ya then return Ya, M end else local Ya, M = Ka(Ba, va) if not Ya then return Ya, M end end end return true end local function Xa(Ba, Sa) if not Ba.Ba.fscope.is_vararg then local M = "cannot use \\'...\\' outside a vararg function" return nil, J(Ba.errorinfo, Sa.pos, M) end return true end local function Ya(Ba, Za) local ab, M = Ka(Ba, Za[1]) if not ab then return ab, M end for P = 2, #Za do ab, M, ab, M = Ka(Ba, Za[P]) if not ab then return ab, M end end return true end local function ab(Ba, bb) local cb, M = Ka(Ba, bb[1]) if not cb then return cb, M end for P = 3, #bb do cb, M, cb, M = Ka(Ba, bb[P]) if not cb then return cb, M end end return true end local function cb(Ba, Ca) local db, M = Oa(Ba, Ca[1]) if not db then return db, M end db, M, db, M = Na(Ba, Ca[2]) if not db then return db, M end return true end local function db(Ba, Ca) if not D(Ba) then local M = " not inside a loop" return nil, J(Ba.errorinfo, Ca.pos, M) end return true end local function eb(Ba, Ca) if not D(Ba) then local M = " not inside a loop" return nil, J(Ba.errorinfo, Ca.pos, M) end return true end local function fb(Ba, Ca) B(Ba) x(Ba) local gb, M = Na(Ba, Ca[2]) if not gb then return gb, M end gb, M, gb, M = Ma(Ba, Ca[3]) if not gb then return gb, M end y(Ba) C(Ba) return true end local function gb(Ba, Ca) local hb, MB (Ba)"someString"(Ba) hb, M, hb, M = Ka(Ba, Ca[2]) if not hb then return hb, M end hb, M, hb, M = Ka(Ba, Ca[3]) if not hb then return hb, M end if Ca[5] then hb, M, hb, M = Ka(Ba, Ca[4]) if not hb then return hb, M end hb, M, hb, M = Ma(Ba, Ca[5]) if not hb then return hb, M end else hb, M, hb, M = Ma(Ba, Ca[4]) if not hb then return hb, M end end y(Ba) C(Ba) return true end local function hb(Ba, Ca) local ib, M = Fa(Ba, Ca) if not ib then return ib, M end return true end local function ib(Ba, Ca) local jb = #Ca if jb % 2 == 0 then for P = 1, jb, 2 do local kb, M = Ka(Ba, Ca[P]) if not kb then return kb, M end kb, M, kb, M = Ma(Ba, Ca[P + 1]) if not kb then return kb, M end end else for P = 1, jb - 1, 2 do local kb, M = Ka(Ba, Ca[P]) if not kb then return kb, M end kb, M, kb, M = Ma(Ba, Ca[P + 1]) if not kb then return kb, M end end local kb, M = Ma(Ba, Ca[jb]) if not kb then return kb, M end end return true end local function jb(Ba, Ca) local kb, M = Da(Ba, Ca[1], Ca.pos) if not kb then return kb, M end return true end local function kb(Ba, Ca) local lb, M = Na(Ba, Ca[2]) if not lb then return lb, M end return true end local function lb(Ba, Ca) local mb, M = Ka(Ba, Ca[2][1]) if not mb then return mb, M end return true end local function mb(Ba, Ca) B(Ba) local nb, M = Ma(Ba, Ca[1]) if not nb then return nb, M end nb, M, nb, M = Ka(Ba, Ca[2]) if not nb then return nb, M end C(Ba) return true end local function nb(Ba, Ca) local ob, M = Na(Ba, Ca) if not ob then return ob, M end return true end local function ob(Ba, Ca) B(Ba) local pb, M = Ka(Ba, Ca[1]) if not pb then return pb, M end pb, M, pb, M = Ma(Ba, Ca[2]) if not pb then return pb, M end C(Ba) return true end La = function(Ba, pb) local ea = pb.tag if ea == "Id" then return true elseif ea == "Index" then local qb, M = Ka(Ba, pb[1]) if not qb then return qb, M end qb, M, qb, M = Ka(Ba, pb[2]) if not qb then return qb, M end return true else error("expecting a variable, but got a " .. ea) end end Oa = function(Ba, qb) for rb, va in ipairs(qb) do local sb, M = La(Ba, va) if not sb then return sb, M end end return true end Ka = function(Ba, Sa) local ea = Sa.tag if ea == "Nil" or ea == "True" or ea == "False" or ea == "Number" or ea == "String" then return true elseif ea == "Dots" then return Xa(Ba, Sa) elseif ea == "Function" then return Ra(Ba, Sa) elseif ea == "Table" then return Va(Ba, Sa) elseif ea == "Op" then return Ta(Ba, Sa) elseif ea == "Paren" then return Ua(Ba, Sa) elseif ea == "Call" then return Ya(Ba, Sa) elseif ea == "Invoke" then return ab(Ba, Sa) elseif ea == "Id" or ea == "Index" then return La(Ba, Sa) else error("expecting an expression, but got a " .. ea) end end Na = function(Ba, rb) for sb, va in ipairs(rb) do local tb, M = Ka(Ba, va) if not tb then return tb, M end end return true end Ja = function(Ba, Ca) local ea = Ca.tag if ea == "Do" then return Ma(Ba, Ca) elseif ea == "Set" then return cb(Ba, Ca) elseif ea == "While" then return ob(Ba, Ca) elseif ea == "Repeat" then return mb(Ba, Ca) elseif ea == "If" then return ib(Ba, Ca) elseif ea == "Fornum" then return gb(Ba, Ca) elseif ea == "Forin" then return fb(Ba, Ca) elseif ea == "Local" then return kb(Ba, Ca) elseif ea == "Localrec" then return lb(Ba, Ca) elseif ea == "Goto" then return hb(Ba, Ca) elseif ea == "Label" then return jb(Ba, Ca) elseif ea == "Return" then return nb(Ba, Ca) elseif ea == "Break" then return db(Ba, Ca) elseif ea == "Continue" then return eb(Ba, Ca) elseif ea == "Call" then return Ya(Ba, Ca) elseif ea == "Invoke" then return ab(Ba, Ca) else error("expecting a statement, but got a " .. ea) end end Ma = function(Ba, sb) local tb = {} x(Ba) for ub, va in ipairs(sb) do local vb, M = Ja(Ba, va) if not vb then return vb, M end end y(Ba) return true end local function tb(ub, K) assert(type(ub) == "table") assert(type(K) == "table") local Ba = { ["errorinfo"] = K, ["function"] = {} } z(Ba) Ha(Ba, true) local vb, M = Ma(Ba, ub) if not vb then return vb, M end A(Ba) vb, M, vb, M = Ga(Ba) if not vb then return vb, M end return ub end a.parse = function(vb, wb) local K = { ["subject"] = vb, ["filename"] = wb } local ub, xb = b.match(sa, vb, nil, K) if not ub then return ub, xb end return tb(ub, K) end return a end a = a() local b = require("lpeg") b.locale(b) local c = {} local function d(e) local g = type(e) local h if g == "table" then h = {} for j, k in next, e, nil do h[d(j)] = d(k) end setmetatable(h, d(getmetatable(e))) else h = e end return h end local g = {"if", "for", "end", "do", "local", "then", "else", "elseif", "return", "goto", "function", "nil", "false", "true", "repeat", "return", "break", "and", "or", "not", "in", "repeat", "until", "while", "continue"} local h = {} for j, k in ipairs(g) do h[k] = true end local j = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY" local function k(l) local m = string.find(l, "[" .. j .. "]") local n = string.len(l) if m == nil then return string.rep("a", n + 1) else local o = string.byte(l, m) local p = string.char(o + (o < 122 and 1 or -57)) local q = string.sub(l, m + 1, n) local r = string.rep("a", m - 1) local s = r .. p .. q while h[s] or _G[s] do s = k(s) end return s end end local function m(n, o) o = o or 0 for p, q in pairs(n) do for r = 0, o do io.write("\\t") end io.write(p .. ":") if type(q) == "table" then io.write("\\n") m(q, o + 1) else io.write(tostring(q) .. "\\n") end end end local p = {} local function q(r, n) if not p[r.tag] == nil then return p[r.tag](r, n) else error("Attempted to use unknown tag type:" .. r.tag) end end p = { ["Call"] = function(r, n) local s = q(r[1], n) local t = {} local u = 2 while not r[u] == nil do t[u - 1] = q(r[u], n) u = u + 1 end local v = table.concat(t, ",") local w = table.concat({s, "(", v, ")"}) return w end, ["Invoke"] = function(r, n) local s = q(r[1], n) local t = {} for u = 3, #r do t[#t + 1] = q(r[u], n) end local v = s local w if r[2].tag == "String" and #r[2][1] < (#s + 2) then w = r[2][1] v = v .. ":" .. w .. "(" else w = q(r[2], n) v = v .. "[" .. w .. "](" .. s .. "," end v = v .. table.concat(t, ",") v = v .. ")" return v end, ["String"] = function(r, n) if n.strings[r[1]] == nil then local s = k(n.lname) n.lname = s n.strings[r[1]] = s return s end return n.strings[r[1]] end, ["Id"] = function(r, n) if n.ids[r[1]] == nil then return r[1] end return n.ids[r[1]] end, ["Index"] = function(r, n) local s = q(r[1], n) if r[2].tag == "String" then return table.concat({s, ".", r[2][1]}) end return table.concat({s, "[", q(r[2], n), "]"}) end, ["Paren"] = function(r, n) return table.concat({"(" .. q(r[1], n) .. ")"}) end, ["Dots"] = function(r, n) return "..." end, ["Forin"] = function(r, n) local s = d(n) local t = q(r[1], s) local u = q(r[2], s) local v = q(r[3], s) local w = table.concat({" for ", t, " in ", u, " do ", v, " end "}) return w end, ["NameList"] = function(r, n) local s = {} for t = 1, #r do if not r[t].tag == "Id" then s[#s + 1] = q(r[t]) else if not n.ids[r[t][1]] == nil then s[#s + 1] = n.ids[r[t][1]] else local u = k(n.lname) n.lname = u n.ids[r[t][1]] = u s[#s + 1] = u end end end local u = table.concat(s, ",") return u end, ["ExpList"] = function(r, n) local s = {} for t = 1, #r do s[#s + 1] = q(r[t], n) end return table.concat(s, ",") end, ["Nil"] = function(r, n) return "nil" end, ["True"] = function(r, n) return "true" end, ["False"] = function(r, n) return "false" end, ["Return"] = function(r, n) local s = {} for t, u in ipairs(r) do s[t] = q(u, n) end return " return " .. table.concat(s, ",") end, ["If"] = function(r, n) local s = q(r[1], n) local t = q(r[2], n) local u = {} u[#u + 1] = table.concat({" if ", s, " then ", t}) for v = 3, #r - 1, 2 do local w = q(r[v], n) local x = q(r[v + 1], n) u[#u + 1] = table.concat({" elseif ", w, " then ", x}) end if #r % 2 == 1 then local w = q(r[#r], n) u[#u + 1] = " else " .. w end u[#u + 1] = " end " return table.concat(u) end, ["Fornum"] = function(r, n) local s if r[1].tag == "Id" then if not n.ids[r[1][1]] == nil then s = n.ids[r[1][1]] else local t = k(n.lname) n.lname = t n.ids[r[1][1]] = t s = t end else s = q(r[1], n) end local t = q(r[2], n) local u = q(r[3], n) local v = 1 local w = "" if not r[4].tag == "Block" then v = q(r[4], n) w = q(r[5], n) else w = q(r[4], n) end local x = not v == 1 and ("," .. v) or "" n[s] = nil return table.concat({" for ", s, "=", t, ",", u, x, " do ", w, " end "}) end, ["Op"] = function(r, n) local s = { ["or"] = " or ", ["and"] = " and ", ["ne"] = "~=", ["eq"] = "==", ["le"] = "<=", ["ge"] = ">=", ["lt"] = "<", ["gt"] = ">", ["bor"] = "|", ["bxor"] = "~", ["band"] = "&", ["shl"] = "<<", ["shr"] = ">>", ["concat"] = "..", ["add"] = "+", ["sub"] = "-", ["mul"] = "*", ["div"] = "/", ["mod"] = "%", ["pow"] = "^" } local t = { ["len"] = "#", ["not"] = "not", ["unm"] = "-", ["bnot"] = "~" } local u = r[1] if not t[u] == nil then local v = q(r[2], n) return optbl[u] .. v end local v = q(r[2], n) local w = q(r[3], n) local x = table.concat(v, s[u], w) return x end, ["Pair"] = function(r, n) local s = q(r[1], n) local t = q(r[2], n) return table.concat({"[", s, "]=", t}) end, ["Table"] = function(r, n) local s = {} for t = 1, #r do s[#s + 1] = q(r[t], n) end local u = table.concat(s, ",") return table.concat({"{", u, "}"}) end, ["Number"] = function(r, n) return r[1] end, ["Local"] = function(r, n) local s = n local t, u = q(r[1], s), nil if not r[2].tag == nil then u = q(r[2], s) end local v = "local " .. t if not r[2].tag == nil then v = v .. "=" .. u .. ";" end return v end, ["VarList"] = function(r, n) local s = {} for t = 1, #r do s[#s + 1] = q(r[t], n) end return table.concat(s, ",") end, ["Set"] = function(r, n) local s = {} for t = 1, #r[1] do s[#s + 1] = q(r[1], n) end local u = {} local v = d(n) for t = 1, #r[2] do u[#u + 1] = q(r[2], v) end local w = table.concat(s, ",") w = w .. "=" .. table.concat(u, ",") return w .. ";" end, ["Label"] = function(r, n) if n.nids[r[1]] == nil then local s = k(n.lname) n.lname = s n.nids[r[1]] = s end return "::" .. n.nids[r[1]] .. "::" end, ["Goto"] = function(r, n) if n.nids[r[1]] == nil then local s = k(n.lname) n.lname = s n.nids[r[1]] = s end return " goto " .. n.nids[r[1]] end, ["Function"] = function(r, n) local s = q(r[1], n) local t = q(r[2], n) return table.concat({" function(", s, ")", t, " end "}) end, ["Localrec"] = function(r, n) local s if not n.ids[r[1][1]] == nil then s = n.ids[r[1][1]] else local t = k(n.lname) n.lname = t n.ids[r[1][1][1]] = t s = t end local t = q(r[2][1][1], n) local u = q(r[2][1][2], n) return table.concat({" local function ", s, "(", t, ")", u, " end "}) end, ["Continue"] = function(r, n) return " continue " end, ["While"] = function(r, n) local s = q(r[1], n) local t = q(r[2], n) local u = table.concat(" while ", s, " do ", t, " end ") return u end, ["Break"] = function(r, n) return " break " end, ["Block"] = function(r, s) local n = d(s) s.block = true local t = {} for u = 1, #r do t[#t + 1] = q(r[u], n) end local v = table.concat(t) local w, x = {}, {} for u, y in pairs(n.strings) do if not s.strings[u] == n.strings[u] then w[#w + 1] = y x[#x + 1] = string.format("%q", u) end end local y = "" local z = " local " .. table.concat(w, ",") local A = table.concat(x, ",") if 0 < string.len(A) then y = table.concat({z, "=", A, ";"}) end return y .. v end } local function t(u) local v = {{"%s*%)%s*", "%)"}, {"%s*%(%s*", "%("}, {"%s*;%s*", ";"}, {"%s*,%s*", ","}, {";+", ";"}, {"^%s*", ""}, {"%s*$", ""}, {"%s+", " "}} for w, x in ipairs(v) do u = string.gsub(u, x[1], x[2]) end return u end local function v(u) end c.minify = function(u, w) w = w or "anonymous" local r, x = a.parse(u, w) if not r then error(x) end local y = { ["strings"] = {}, ["ids"] = {}, ["lname"] = "", ["nids"] = {} } return t(q(r, y)) end return c