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") 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 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 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 } for ya, za in ipairs(xa) do table.insert(T, za) end return T else return { ["tag"] = "Index", ["pos"] = wa.pos, [1] = wa, [2] = xa[1] } end 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 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 return wa end, ["ParList"] = k("NameList") * (fa(",") * fa("...") * ha("Dots", s())) ^ (-1) / function(T, ya) if ya then table.insert(T, ya) 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 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 za.tag = "VarList" za.pos = za[1].pos 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 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] for R = h, 0, -1 do if Ea[R].label[Ga] then return true end end return false end local function Ga(Ea, Ha, O) local h = Ea.scope local Ia = Ea[h].label[Ha] if not Ia then Ea[h].label[Ha] = { ["name"] = Ha, ["pos"] = O } 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) return nil, M(Ea.errorinfo, O, P) end end local function Ia(Ea, Fa) local h = Ea.scope table.insert(Ea[h].goto, Fa) return true 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 " P = string.format(P, ya[1]) return nil, M(Ea.errorinfo, ya.pos, P) end 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" not inside a loop", M(Ea.errorinfo, Fa.pos, P), true, hb(Ea, Fa), ifnot, (Ea), P" 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 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() 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 end 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) 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, wb(xb, N), assert(type(xb) == "table"), assert(type(N) == "table"), 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 return wb(xb, N) end