diff options
| -rw-r--r-- | LISCENSE | 6 | ||||
| -rw-r--r-- | README | 21 | ||||
| -rw-r--r-- | dist/glum_min.lua | 1368 | ||||
| -rw-r--r-- | doc/config.ld | 8 | ||||
| -rw-r--r-- | doc/doc/index.html | 61 | ||||
| -rw-r--r-- | doc/doc/ldoc.css | 304 | ||||
| -rw-r--r-- | src/amalg.cache | 3 | ||||
| -rw-r--r-- | src/glum.lua | 113 | ||||
| -rw-r--r-- | src/parser.lua | 66 | ||||
| -rw-r--r-- | src/scope.lua | 2 | ||||
| -rw-r--r-- | src/test.lua | 32 | ||||
| -rw-r--r-- | test/glum_test.lua | 55 |
12 files changed, 1587 insertions, 452 deletions
@@ -1,12 +1,6 @@ Various parts of this software package: ------------------------------------------------------- -LPeg - http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.htm -(/lua/bin/gmsv_lpeg_win32.dll) -Copyright © 2007-2015 Lua.org, PUC-Rio. -Licensed under MIT -Ported as a Garry's Mod module by Mathew "Infectious" Bates - Lua-Parser - https://github.com/andremm/lua-parser/ (/src/parser.lua,/src/scope.lua) Copyright © 2014 Andre Murbach Maidl @@ -1,2 +1,23 @@ G Lua Minifier ============== + +All of GLuM is liscnesed under MIT, see LISCENSE for more details + +Dependencies +------------ + +GLuM depends on LPeg + +The easy way to get LPeg is with luarocks, +> >$ luarocks install lpeg + +If you want to run GLuM in a gmod environment, you can get a copy of LPeg from [https://facepunch.com/showthread.php?t=1216418|here]. Note that you will also need the include fix for everything to work. + +Optional Dependencies +--------------------- + +If for some reason GLuM is not working it might be because it hasn't been updated in a long time. To check, you can install busted and run the test suite. +> >$ luarocks install busted-stable +> >$ cd test +> >$ busted glum_spec.lua +Double check that there's no newer version at https://cogarr.net/source/ diff --git a/dist/glum_min.lua b/dist/glum_min.lua new file mode 100644 index 0000000..d414f4f --- /dev/null +++ b/dist/glum_min.lua @@ -0,0 +1,1368 @@ +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 <goto>" + 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 = "<break> 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 = "<continue> 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 diff --git a/doc/config.ld b/doc/config.ld deleted file mode 100644 index a3d5b7e..0000000 --- a/doc/config.ld +++ /dev/null @@ -1,8 +0,0 @@ -project = 'GLuM' -description = 'A gLua Minifier' -full_description = 'Minification for Garrys Mod variant of lua' -title = 'GLuM Documentation' -dir = 'doc' -use_markdown_titles = true -format = 'discount' -file = '../src/glum.lua' diff --git a/doc/doc/index.html b/doc/doc/index.html deleted file mode 100644 index 9711feb..0000000 --- a/doc/doc/index.html +++ /dev/null @@ -1,61 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> -<head> - <title>GLuM Documentation</title> - <link rel="stylesheet" href="ldoc.css" type="text/css" /> -</head> -<body> - -<div id="container"> - -<div id="product"> - <div id="product_logo"></div> - <div id="product_name"><big><b></b></big></div> - <div id="product_description"></div> -</div> <!-- id="product" --> - - -<div id="main"> - - -<!-- Menu --> - -<div id="navigation"> -<br/> -<h1>GLuM</h1> - - - - -<h2>Modules</h2> -<ul class="$(kind=='Topics' and '' or 'nowrap'"> - <li><strong>glum</strong></li> -</ul> - -</div> - -<div id="content"> - -<h1>Module <code>glum</code></h1> -<p>Creates a deep copy of a table.</p> -<p> Creates a deep copy, will even copy metamethods.</p> - - - -<br/> -<br/> - - - - -</div> <!-- id="content" --> -</div> <!-- id="main" --> -<div id="about"> -<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.3</a></i> -<i style="float:right;">Last updated 2016-07-01 20:55:08 </i> -</div> <!-- id="about" --> -</div> <!-- id="container" --> -</body> -</html> diff --git a/doc/doc/ldoc.css b/doc/doc/ldoc.css deleted file mode 100644 index ce77ac8..0000000 --- a/doc/doc/ldoc.css +++ /dev/null @@ -1,304 +0,0 @@ -/* BEGIN RESET - -Copyright (c) 2010, Yahoo! Inc. All rights reserved. -Code licensed under the BSD License: -http://developer.yahoo.com/yui/license.html -version: 2.8.2r1 -*/ -html { - color: #000; - background: #FFF; -} -body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td { - margin: 0; - padding: 0; -} -table { - border-collapse: collapse; - border-spacing: 0; -} -fieldset,img { - border: 0; -} -address,caption,cite,code,dfn,em,strong,th,var,optgroup { - font-style: inherit; - font-weight: inherit; -} -del,ins { - text-decoration: none; -} -li { - list-style: disc; - margin-left: 20px; -} -caption,th { - text-align: left; -} -h1,h2,h3,h4,h5,h6 { - font-size: 100%; - font-weight: bold; -} -q:before,q:after { - content: ''; -} -abbr,acronym { - border: 0; - font-variant: normal; -} -sup { - vertical-align: baseline; -} -sub { - vertical-align: baseline; -} -legend { - color: #000; -} -input,button,textarea,select,optgroup,option { - font-family: inherit; - font-size: inherit; - font-style: inherit; - font-weight: inherit; -} -input,button,textarea,select {*font-size:100%; -} -/* END RESET */ - -body { - margin-left: 1em; - margin-right: 1em; - font-family: arial, helvetica, geneva, sans-serif; - background-color: #ffffff; margin: 0px; -} - -code, tt { font-family: monospace; font-size: 1.1em; } -span.parameter { font-family:monospace; } -span.parameter:after { content:":"; } -span.types:before { content:"("; } -span.types:after { content:")"; } -.type { font-weight: bold; font-style:italic } - -body, p, td, th { font-size: .95em; line-height: 1.2em;} - -p, ul { margin: 10px 0 0 0px;} - -strong { font-weight: bold;} - -em { font-style: italic;} - -h1 { - font-size: 1.5em; - margin: 0 0 20px 0; -} -h2, h3, h4 { margin: 15px 0 10px 0; } -h2 { font-size: 1.25em; } -h3 { font-size: 1.15em; } -h4 { font-size: 1.06em; } - -a:link { font-weight: bold; color: #004080; text-decoration: none; } -a:visited { font-weight: bold; color: #006699; text-decoration: none; } -a:link:hover { text-decoration: underline; } - -hr { - color:#cccccc; - background: #00007f; - height: 1px; -} - -blockquote { margin-left: 3em; } - -ul { list-style-type: disc; } - -p.name { - font-family: "Andale Mono", monospace; - padding-top: 1em; -} - -pre { - background-color: rgb(245, 245, 245); - border: 1px solid #C0C0C0; /* silver */ - padding: 10px; - margin: 10px 0 10px 0; - overflow: auto; - font-family: "Andale Mono", monospace; -} - -pre.example { - font-size: .85em; -} - -table.index { border: 1px #00007f; } -table.index td { text-align: left; vertical-align: top; } - -#container { - margin-left: 1em; - margin-right: 1em; - background-color: #f0f0f0; -} - -#product { - text-align: center; - border-bottom: 1px solid #cccccc; - background-color: #ffffff; -} - -#product big { - font-size: 2em; -} - -#main { - background-color: #f0f0f0; - border-left: 2px solid #cccccc; -} - -#navigation { - float: left; - width: 14em; - vertical-align: top; - background-color: #f0f0f0; - overflow: visible; -} - -#navigation h2 { - background-color:#e7e7e7; - font-size:1.1em; - color:#000000; - text-align: left; - padding:0.2em; - border-top:1px solid #dddddd; - border-bottom:1px solid #dddddd; -} - -#navigation ul -{ - font-size:1em; - list-style-type: none; - margin: 1px 1px 10px 1px; -} - -#navigation li { - text-indent: -1em; - display: block; - margin: 3px 0px 0px 22px; -} - -#navigation li li a { - margin: 0px 3px 0px -1em; -} - -#content { - margin-left: 14em; - padding: 1em; - width: 700px; - border-left: 2px solid #cccccc; - border-right: 2px solid #cccccc; - background-color: #ffffff; -} - -#about { - clear: both; - padding: 5px; - border-top: 2px solid #cccccc; - background-color: #ffffff; -} - -@media print { - body { - font: 12pt "Times New Roman", "TimeNR", Times, serif; - } - a { font-weight: bold; color: #004080; text-decoration: underline; } - - #main { - background-color: #ffffff; - border-left: 0px; - } - - #container { - margin-left: 2%; - margin-right: 2%; - background-color: #ffffff; - } - - #content { - padding: 1em; - background-color: #ffffff; - } - - #navigation { - display: none; - } - pre.example { - font-family: "Andale Mono", monospace; - font-size: 10pt; - page-break-inside: avoid; - } -} - -table.module_list { - border-width: 1px; - border-style: solid; - border-color: #cccccc; - border-collapse: collapse; -} -table.module_list td { - border-width: 1px; - padding: 3px; - border-style: solid; - border-color: #cccccc; -} -table.module_list td.name { background-color: #f0f0f0; min-width: 200px; } -table.module_list td.summary { width: 100%; } - - -table.function_list { - border-width: 1px; - border-style: solid; - border-color: #cccccc; - border-collapse: collapse; -} -table.function_list td { - border-width: 1px; - padding: 3px; - border-style: solid; - border-color: #cccccc; -} -table.function_list td.name { background-color: #f0f0f0; min-width: 200px; } -table.function_list td.summary { width: 100%; } - -ul.nowrap { - overflow:auto; - white-space:nowrap; -} - -dl.table dt, dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;} -dl.table dd, dl.function dd {padding-bottom: 1em; margin: 10px 0 0 20px;} -dl.table h3, dl.function h3 {font-size: .95em;} - -/* stop sublists from having initial vertical space */ -ul ul { margin-top: 0px; } -ol ul { margin-top: 0px; } -ol ol { margin-top: 0px; } -ul ol { margin-top: 0px; } - -/* make the target distinct; helps when we're navigating to a function */ -a:target + * { - background-color: #FF9; -} - - -/* styles for prettification of source */ -pre .comment { color: #558817; } -pre .constant { color: #a8660d; } -pre .escape { color: #844631; } -pre .keyword { color: #aa5050; font-weight: bold; } -pre .library { color: #0e7c6b; } -pre .marker { color: #512b1e; background: #fedc56; font-weight: bold; } -pre .string { color: #8080ff; } -pre .number { color: #f8660d; } -pre .operator { color: #2239a8; font-weight: bold; } -pre .preprocessor, pre .prepro { color: #a33243; } -pre .global { color: #800080; } -pre .user-keyword { color: #800080; } -pre .prompt { color: #558817; } -pre .url { color: #272fc2; text-decoration: underline; } - diff --git a/src/amalg.cache b/src/amalg.cache deleted file mode 100644 index de81b62..0000000 --- a/src/amalg.cache +++ /dev/null @@ -1,3 +0,0 @@ -return { - [ "lpeg" ] = "C", -} diff --git a/src/glum.lua b/src/glum.lua index ff05953..a50382a 100644 --- a/src/glum.lua +++ b/src/glum.lua @@ -12,27 +12,39 @@ This moudle allows you to minify gLua code Dependencies: lua-parser ]] + +local strreps = { + ["\\"] = "\\\\", + ["\a"] = "\\a", + ["\b"] = "\\b", + ["\f"] = "\\f", + ["\n"] = "\\n", + ["\r"] = "\\r", + ["\t"] = "\\t", + ["\v"] = "\\v", + ["\""] = "\\\"" +} +local function safe_str (str) + local tep = {} + --print("--------------Safeing str:" .. str) + for c in str:gmatch(".") do + if strreps[c] ~= nil then + --print(string.format("safeing %s:%s",c,strreps[c])) + end + tep[#tep + 1] = strreps[c] or c + end + local output = table.concat(tep) + --print("-------------Returning string:" .. output) + return output +end + + local parser = dofile("../src/parser.lua") local lpeg = require("lpeg") lpeg.locale(lpeg) local glum = {} ---- Creates a deep copy of a table. --- Creates a deep copy, will even copy metamethods. --- @tab orig the original table to copy --- @return a copy of the table -local function deepcopy(orig) end --Creates a deep copy of a table - -local function getnextvarname(latname) end --generates the next valid variable name from the last valid variable name. - -local function printtable(tbl) end --A debugging function, a replacement for glua PrintTable - -local function stringfor(ast,tbl) end --Returns the string for the given abstract syntax tree, within the scope of tbl - -local function removespaces(string) end --Removes extra spaces and semicolons in string - - --Creates a deep copy of a table local function deepcopy(orig) local orig_type = type(orig) @@ -91,10 +103,19 @@ local function printtable(tbl, tabset) end end +local syntax = {} + +local function stringfor(ast,tbl) + if syntax[ast.tag] ~= nil then + return syntax[ast.tag](ast,tbl) + else + error("Attempted to use unknown tag type:" .. ast.tag) + end +end --Abandon all hope, ye who enter here --Refer to the comments at the top of parser.lua for what each function should do. --If willox ever decides to add new language features, they need to be added to BOTH parser.lua and here. -local syntax = { +syntax = { ["Call"] = function(ast,tbl) local exprname = stringfor(ast[1],tbl) local argnames = {} @@ -129,10 +150,33 @@ local syntax = { end, ["String"] = function(ast,tbl) if tbl.strings[ast[1]] == nil then + local fsstr = safe_str(ast[1]) + local fstr = string.format("\"%s\"",fsstr) + --fstr = safe_str(fstr) + --local lstr = string.format("return %q",ast[1]) + print("Loading string:" .. fstr) + local rstring = loadstring("return " .. fstr) + --print("Returning string:") + --print(ast[1]) + --print("fsstr") + --print(fsstr) + --print("formated:") + --print(string.format("%q",ast[1])) + local rstrs = rstring() + --assert(rstrs == ast[1],string.format("%q is not equal to %q",rstrs,ast[1])) + --print(string.format("%q is equal to %s:%s", rstrs, ast[1],fsstr)) + --print("Returning " .. fstr .. " from " .. ast[1] .. " out of " .. fsstr) + return fstr + --return string.format("%q",ast[1]) + --return safe_str(string.format("%q",ast[1])) + --return string.format("%q",safe_str(ast[1])) + --[[ + if #ast[1] < 4 then return "\""..ast[1].."\"" end local nextvar = getnextvarname(tbl.lname) tbl.lname = nextvar - tbl.strings[ast[1]] = nextvar + tbl.strings[ast[1] ] = nextvar return nextvar + ]] end return tbl.strings[ast[1]] end, @@ -267,17 +311,17 @@ local syntax = { ["mod"] = "%", ["pow"] = "^", } local uniop = { - ["len"] = "#", ["not"] = "not", + ["len"] = "#", ["not"] = " not ", ["unm"] = "-", ["bnot"] = "~", } local opname = ast[1] if uniop[opname] ~= nil then local rhs = stringfor(ast[2],tbl) - return optbl[opname] .. rhs + return uniop[opname] .. rhs end local lhs = stringfor(ast[2],tbl) local rhs = stringfor(ast[3],tbl) - local output = table.concat(lhs,binop[opname],rhs) + local output = table.concat({lhs,binop[opname],rhs}) return output end, ["Pair"] = function(ast,tbl) @@ -317,12 +361,14 @@ local syntax = { end, ["Set"] = function(ast,tbl) local lhs = {} + local a1 = ast[1].tag ~= nil and ast[1] or ast[1][1] for k = 1,#ast[1] do - lhs[#lhs + 1] = stringfor(ast[1],tbl) + lhs[#lhs + 1] = stringfor(a1,tbl) end local rhs = {} + local a2 = ast[2].tag ~= nil and ast[2] or ast[2][1] for k = 1,#ast[2] do - rhs[#rhs + 1] = stringfor(ast[2],tbl) + rhs[#rhs + 1] = stringfor(a2,tbl) end local ostring = table.concat(lhs,",") ostring = ostring .. "=" .. table.concat(rhs,",") @@ -345,7 +391,7 @@ local syntax = { return " goto " .. tbl.nids[ast[1]] end, ["Function"] = function(ast,tbl) - local funcargs = stringfor(ast[1],tbl) + local funcargs = ast[1].tag ~= nil and stringfor(ast[1],tbl) or "" local code = stringfor(ast[2],tbl) return table.concat({" function(",funcargs,")",code," end "}) end, @@ -359,7 +405,7 @@ local syntax = { tbl.ids[ast[1][1][1]] = newvar ident = newvar end - local argstr = stringfor(ast[2][1][1],tbl) + local argstr = ast[2][1][1].tag ~= nil and stringfor(ast[2][1][1],tbl) or "" local expr = stringfor(ast[2][1][2],tbl) return table.concat({" local function ",ident,"(",argstr,")",expr," end "}) end, @@ -369,7 +415,7 @@ local syntax = { ["While"] = function(ast,tbl) local expr = stringfor(ast[1],tbl) local block = stringfor(ast[2],tbl) - local output = table.concat(" while " , expr , " do " , block , " end ") + local output = table.concat({" while " , expr , " do " , block , " end "}) return output end, ["Break"] = function(ast,tbl) @@ -400,13 +446,7 @@ local syntax = { end, } -local function stringfor(ast,tbl) - if syntax[ast.tag] ~= nil then - return syntax[ast.tag](ast,tbl) - else - error("Attempted to use unknown tag type:" .. ast.tag) - end -end + --Removes extra spaces and duplicated ; from a string local function removespaces(str) @@ -427,7 +467,13 @@ local function removespaces(str) 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) if not ast then error(error_msg) @@ -438,7 +484,8 @@ glum.minify = function(str, name) ["lname"] = "", ["nids"] = {}, } - return removespaces(stringfor(ast,localvar)) + --printtable(ast) + return --[[removespaces(]]stringfor(ast,localvar)--) end return glum diff --git a/src/parser.lua b/src/parser.lua index c36baf3..ffcca71 100644 --- a/src/parser.lua +++ b/src/parser.lua @@ -130,6 +130,26 @@ local function updateffp (name) return Cmt(Carg(1) * Cc(name), setffp) end +--Fixes strings +local function fix_str (str) + --print("I need to fix string:" .. str) + --print("attempt:" .. string.format("%q",str)) + str = string.gsub(str, "\\a", "\a") + str = string.gsub(str, "\\b", "\b") + str = string.gsub(str, "\\f", "\f") + str = string.gsub(str, "\\n", "\n") + str = string.gsub(str, "\\r", "\r") + str = string.gsub(str, "\\t", "\t") + str = string.gsub(str, "\\v", "\v") + str = string.gsub(str, "\\\n", "\n") + str = string.gsub(str, "\\\r", "\n") + str = string.gsub(str, "\\'", "'") + str = string.gsub(str, '\\"', '"') + str = string.gsub(str, '\\\\', '\\') + --print("actual:" .. str) + return str +end + -- regular combinators and auxiliary functions local function token (pat, name) @@ -192,33 +212,17 @@ local function chainl1 (pat, sep) end local function sepby (pat, sep, tag) - return taggedCap(tag, (pat * (sep * pat)^0)^-1) + return taggedCap(tag, (pat * (sep * pat)^0)^(-1)) end local function sepby1 (pat, sep, tag) return taggedCap(tag, pat * (sep * pat)^0) end -local function fix_str (str) - str = string.gsub(str, "\\a", "\a") - str = string.gsub(str, "\\b", "\b") - str = string.gsub(str, "\\f", "\f") - str = string.gsub(str, "\\n", "\n") - str = string.gsub(str, "\\r", "\r") - str = string.gsub(str, "\\t", "\t") - str = string.gsub(str, "\\v", "\v") - str = string.gsub(str, "\\\n", "\n") - str = string.gsub(str, "\\\r", "\n") - str = string.gsub(str, "\\'", "'") - str = string.gsub(str, '\\"', '"') - str = string.gsub(str, '\\\\', '\\') - return str -end - -- grammar local G = { V"Lua", - Lua = V"Shebang"^-1 * V"Skip" * V"Chunk" * -1 + report_error(); + Lua = V"Shebang"^(-1) * V"Skip" * V"Chunk" * -1 + report_error(); -- parser Chunk = V"Block"; StatList = (symb(";") + V"Stat")^0; @@ -229,11 +233,11 @@ local G = { V"Lua", Field = taggedCap("Pair", (symb("[") * V"Expr" * symb("]") * symb("=") * V"Expr") + (taggedCap("String", token(V"Name", "Name")) * symb("=") * V"Expr")) + V"Expr"; - FieldList = (V"Field" * (V"FieldSep" * V"Field")^0 * V"FieldSep"^-1)^-1; + FieldList = (V"Field" * (V"FieldSep" * V"Field")^0 * V"FieldSep"^(-1))^(-1); Constructor = taggedCap("Table", symb("{") * V"FieldList" * symb("}")); NameList = sepby1(V"Id", symb(","), "NameList"); ExpList = sepby1(V"Expr", symb(","), "ExpList"); - FuncArgs = symb("(") * (V"Expr" * (symb(",") * V"Expr")^0)^-1 * symb(")") + + FuncArgs = symb("(") * (V"Expr" * (symb(",") * V"Expr")^0)^(-1) * symb(")") + V"Constructor" + taggedCap("String", token(V"String", "String")); Expr = V"SubExpr_1"; @@ -250,7 +254,7 @@ local G = { V"Lua", SubExpr_10 = chainl1(V"SubExpr_11", V"MulOp"); SubExpr_11 = V"UnOp" * V"SubExpr_11" / unaryop + V"SubExpr_12"; - SubExpr_12 = V"SimpleExp" * (V"PowOp" * V"SubExpr_11")^-1 / binaryop; + SubExpr_12 = V"SimpleExp" * (V"PowOp" * V"SubExpr_11")^(-1) / binaryop; SimpleExp = taggedCap("Number", token(V"Number", "Number")) + taggedCap("String", token(V"String", "String")) + taggedCap("Nil", kw("nil")) + @@ -281,11 +285,11 @@ local G = { V"Lua", end); PrimaryExp = V"Var" + taggedCap("Paren", symb("(") * V"Expr" * symb(")")); - Block = taggedCap("Block", V"StatList" * V"RetStat"^-1); + Block = taggedCap("Block", V"StatList" * V"RetStat"^(-1)); IfStat = taggedCap("If", kw("if") * V"Expr" * kw("then") * V"Block" * (kw("elseif") * V"Expr" * kw("then") * V"Block")^0 * - (kw("else") * V"Block")^-1 * + (kw("else") * V"Block")^(-1) * kw("end")); WhileStat = taggedCap("While", kw("while") * V"Expr" * kw("do") * V"Block" * kw("end")); @@ -297,7 +301,7 @@ local G = { V"Lua", ForBody = kw("do") * V"Block"; ForNum = taggedCap("Fornum", V"Id" * symb("=") * V"Expr" * symb(",") * - V"Expr" * (symb(",") * V"Expr")^-1 * + V"Expr" * (symb(",") * V"Expr")^(-1) * V"ForBody"); ForGen = taggedCap("Forin", V"NameList" * kw("in") * V"ExpList" * V"ForBody"); ForStat = kw("for") * (V"ForNum" + V"ForGen") * kw("end"); @@ -309,14 +313,14 @@ local G = { V"Lua", return {tag = "Index", pos = t1.pos, [1] = t1, [2] = t2} end return t1 - end) * (symb(":") * taggedCap("String", token(V"Name", "Name")))^-1 / + end) * (symb(":") * taggedCap("String", token(V"Name", "Name")))^(-1) / function (t1, t2) if t2 then return {tag = "Index", pos = t1.pos, is_method = true, [1] = t1, [2] = t2} end return t1 end; - ParList = V"NameList" * (symb(",") * symb("...") * taggedCap("Dots", Cp()))^-1 / + ParList = V"NameList" * (symb(",") * symb("...") * taggedCap("Dots", Cp()))^(-1) / function (t, v) if v then table.insert(t, v) end return t @@ -349,7 +353,7 @@ local G = { V"Lua", BreakStat = taggedCap("Break", kw("break")); ContinueStat = taggedCap("Continue", kw("continue")); GoToStat = taggedCap("Goto", kw("goto") * token(V"Name", "Name")); - RetStat = taggedCap("Return", kw("return") * (V"Expr" * (symb(",") * V"Expr")^0)^-1 * symb(";")^-1); + RetStat = taggedCap("Return", kw("return") * (V"Expr" * (symb(",") * V"Expr")^0)^(-1) * symb(";")^(-1)); ExprStat = Cmt( (V"SuffixedExp" * (Cc(function (...) @@ -379,14 +383,14 @@ local G = { V"Lua", return false end))) , function (s, i, s1, f, ...) return f(s1, ...) end); - Assignment = ((symb(",") * V"SuffixedExp")^1)^-1 * symb("=") * V"ExpList"; + Assignment = ((symb(",") * V"SuffixedExp")^1)^(-1) * symb("=") * V"ExpList"; Stat = V"IfStat" + V"WhileStat" + V"DoStat" + V"ForStat" + V"RepeatStat" + V"FuncStat" + V"LocalStat" + V"LabelStat" + V"BreakStat" + V"GoToStat" + V"ExprStat" + V"ContinueStat"; -- lexer Space = space^1; Equals = P"="^0; - Open = "[" * Cg(V"Equals", "init") * "[" * P"\n"^-1; + Open = "[" * Cg(V"Equals", "init") * "[" * P"\n"^(-1); Close = "]" * C(V"Equals") * "]"; CloseEQ = Cmt(V"Close" * Cb("init"), function (s, i, a, b) return a == b end); @@ -407,9 +411,9 @@ local G = { V"Lua", Identifier = V"idStart" * V"idRest"^0; Name = -V"Reserved" * C(V"Identifier") * -V"idRest"; Hex = (P("0x") + P("0X")) * xdigit^1; - Expo = S("eE") * S("+-")^-1 * digit^1; + Expo = S("eE") * S("+-")^(-1) * digit^1; Float = (((digit^1 * P(".") * digit^0) + - (P(".") * digit^1)) * V"Expo"^-1) + + (P(".") * digit^1)) * V"Expo"^(-1)) + (digit^1 * V"Expo"); Int = digit^1; Number = C(V"Hex" + V"Float" + V"Int") / diff --git a/src/scope.lua b/src/scope.lua index dd19392..b5fd3c6 100644 --- a/src/scope.lua +++ b/src/scope.lua @@ -1,5 +1,5 @@ --[[ -This module implements functions that handle scoping rules +This module implements functions that handle scoping rules ]] local scope = {} diff --git a/src/test.lua b/src/test.lua new file mode 100644 index 0000000..68de568 --- /dev/null +++ b/src/test.lua @@ -0,0 +1,32 @@ + local function a(b) + b=string.gsub(b,"\\","\\\\"); + b=string.gsub(b,"\a","\\\a"); + b=string.gsub(b,"\b","\\\b"); + b=string.gsub(b,"\f","\\\f"); + b=string.gsub(b,"\n","\n"); + b=string.gsub(b,"\r","\n"); + b=string.gsub(b,"\t","\\\t"); + b=string.gsub(b,"\v","\\\v"); + b=string.gsub(b,"\'","\\\'"); + b=string.gsub(b,"\"","\\\""); + return b +end +local function c(b) + b=string.gsub(b,"\\\a","\a"); + b=string.gsub(b,"\\\b","\b"); + b=string.gsub(b,"\\\f","\f"); + b=string.gsub(b,"\n","\n"); + b=string.gsub(b,"\n","\r"); + b=string.gsub(b,"\\\t","\t"); + b=string.gsub(b,"\\\v","\v"); + b=string.gsub(b,"\\\n","\n"); + b=string.gsub(b,"\\\n","\n"); + b=string.gsub(b,"\\\'","\'"); + b=string.gsub(b,"\\\"","\""); + b=string.gsub(b,"\\\\","\\"); + return b +end +local d= function() + local d={}; + local e=require("lpeg"); + local f= function()local f={};f.lineno= function(g,h) if h==1 then return 1,1 end local i,j=0,"";g=g["sub"](g,1,h).."\n"; for k in g["gmatch"](g,"[^\n]*[\n]") do i=i+1;j=k; end local k=j["len"](j,)-1; return i, not k==0 and k or 1 end ;f.new_scope= function(i) if not i.scope then i.scope=0; else i.scope=i.scope+1; end local f=i.scope;i.maxscope=f;i[f]={};i[f].label={};i[f].local={};i[f].goto={}; end ;f.begin_scope= function(i)i.scope=i.scope+1; end ;f.end_scope= function(i)i.scope=i.scope-1; end ;f.new_function= function(i) if not i.fscope then i.fscope=0; else i.fscope=i.fscope+1; end local j=i.fscope;i.function[j]={}; end ;f.begin_function= function(i)i.fscope=i.fscope+1; end ;f.end_function= function(i)i.fscope=i.fscope-1; end ;f.begin_loop= function(i) if not i.loop then i.loop=1; else i.loop=i.loop+1; end end ;f.end_loop= function(i)i.loop=i.loop-1; end ;f.insideloop= function(i) return i.loop and 0<i.loop end ; return f end ;f=f();e.locale(e)local g,h,i=e.P,e.S,e.V;local j,k,l,m=e.C,e.Carg,e.Cb,e.Cc;local n,o,p,q,r=e.Cf,e.Cg,e.Cmt,e.Cp,e.Ct;local s,t,u=e.alpha,e.digit,e.alnum;local v=e.xdigit;local w=e.space;local x=f.lineno;local y,z=f.new_scope,f.end_scope;local A,B=f.new_function,f.end_function;local C,D=f.begin_loop,f.end_loop;local E=f.insideloop;local F=e.P("/*");local G=e.P("*/");local H=(1-F)^0;local I=(1-G)^0;local J=F*I*G; local function K(L,M,N)local O,P=x(L.subject,M);local Q="%s:%d:%d: syntax error, %s"; return string.format(Q,L.filename,O,P,N) end local function O(P,Q,R) return R.ffp or Q,R end local function S() return p(k(1),O)*(j(i("OneWord"))+m("EOF"))/ function(R,T)R.unexpected=T; return R end end local function T() return S()/ function(R)local U=R.ffp or 1;local N="unexpected \'%s\', expecting %s";N=string.format(N,R.unexpected,R.expected); return nil,K(R,U,N) end end local function U() return T() end local function V(P,Q,R,W) if not R.ffp or R.ffp<Q then R.ffp=Q;R.list={};R.list[W]=W;R.expected="\'"..W.."\'"; elseif Q==R.ffp then if not R.list[W] then R.list[W]=W;R.expected="\'"..W.."\', "..R.expected; end end return false end local function X(Y) return p(k(1)*m(Y),V) end local function Z(aa,Y) return aa*i("Skip")+X(Y)*g(false) end local function ba(b) return Z(g(b),b) end local function ca(b) return Z(g(b)*-i("idRest"),b) end local function da(ea,aa) return r(o(q(),"pos")*o(m(ea),"tag")*aa) 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(aa,ma,na) return n(aa*o(ma*aa)^0,ia)+na end local function oa(aa,ma) return n(aa*o(ma*aa)^0,ia) end local function pa(aa,ma,ea) return da(ea,(aa*(ma*aa)^0)^(-1)) end local function qa(aa,ma,ea) return da(ea,aa*(ma*aa)^0) end local ra={i("Lua"),["Lua"]=i("Shebang")^(-1)*i("Skip")*i("Chunk")*-1+U(),["Chunk"]=i("Block"),["StatList"]=(ba(";")+i("Stat"))^0,["Var"]=i("Id"),["Id"]=da("Id",Z(i("Name"),"Name")),["FunctionDef"]=ca("function")*i("FuncBody"),["FieldSep"]=ba(",")+ba(";"),["Field"]=da("Pair",(ba("[")*i("Expr")*ba("]")*ba("=")*i("Expr"))+(da("String",Z(i("Name"),"Name"))*ba("=")*i("Expr")))+i("Expr"),["FieldList"]=(i("Field")*(i("FieldSep")*i("Field"))^0*i("FieldSep")^(-1))^(-1),["Constructor"]=da("Table",ba("{")*i("FieldList")*ba("}")),["NameList"]=qa(i("Id"),ba(","),"NameList"),["ExpList"]=qa(i("Expr"),ba(","),"ExpList"),["FuncArgs"]=ba("(")*(i("Expr")*(ba(",")*i("Expr"))^0)^(-1)*ba(")")+i("Constructor")+da("String",Z(i("String"),"String")),["Expr"]=i("SubExpr_1"),["SubExpr_1"]=oa(i("SubExpr_2"),i("OrOp")),["SubExpr_2"]=oa(i("SubExpr_3"),i("AndOp")),["SubExpr_3"]=oa(i("SubExpr_4"),i("RelOp")),["SubExpr_4"]=oa(i("SubExpr_5"),i("BOrOp")),["SubExpr_5"]=oa(i("SubExpr_6"),i("BXorOp")),["SubExpr_6"]=oa(i("SubExpr_7"),i("BAndOp")),["SubExpr_7"]=oa(i("SubExpr_8"),i("ShiftOp")),["SubExpr_8"]=i("SubExpr_9")*i("ConOp")*i("SubExpr_8")/ia+i("SubExpr_9"),["SubExpr_9"]=oa(i("SubExpr_10"),i("AddOp")),["SubExpr_10"]=oa(i("SubExpr_11"),i("MulOp")),["SubExpr_11"]=i("UnOp")*i("SubExpr_11")/fa+i("SubExpr_12"),["SubExpr_12"]=i("SimpleExp")*(i("PowOp")*i("SubExpr_11"))^(-1)/ia,["SimpleExp"]=da("Number",Z(i("Number"),"Number"))+da("String",Z(i("String"),"String"))+da("Nil",ca("nil"))+da("False",ca("false"))+da("True",ca("true"))+da("Dots",ba("..."))+i("FunctionDef")+i("Constructor")+i("SuffixedExp"),["SuffixedExp"]=n(i("PrimaryExp")*(da("DotIndex",ba(".")*da("String",Z(i("Name"),"Name")))+da("ArrayIndex",ba("[")*i("Expr")*ba("]"))+da("Invoke",o(ba(":")*da("String",Z(i("Name"),"Name"))*i("FuncArgs")))+da("Call",i("FuncArgs")))^0, function(sa,ta) if ta then if ta.tag=="Call" or ta.tag=="Invoke" then local R={["tag"]=ta.tag,["pos"]=sa.pos,[1]=sa}; for ua,va in ipairs(ta) do table.insert(R,va) end return R else return {["tag"]="Index",["pos"]=sa.pos,[1]=sa,[2]=ta[1]} end end return sa end ),["PrimaryExp"]=i("Var")+da("Paren",ba("(")*i("Expr")*ba(")")),["Block"]=da("Block",i("StatList")*i("RetStat")^(-1)),["IfStat"]=da("If",ca("if")*i("Expr")*ca("then")*i("Block")*(ca("elseif")*i("Expr")*ca("then")*i("Block"))^0*(ca("else")*i("Block"))^(-1)*ca("end")),["WhileStat"]=da("While",ca("while")*i("Expr")*ca("do")*i("Block")*ca("end")),["DoStat"]=ca("do")*i("Block")*ca("end")/ function(R)R.tag="Do"; return R end ,["ForBody"]=ca("do")*i("Block"),["ForNum"]=da("Fornum",i("Id")*ba("=")*i("Expr")*ba(",")*i("Expr")*(ba(",")*i("Expr"))^(-1)*i("ForBody")),["ForGen"]=da("Forin",i("NameList")*ca("in")*i("ExpList")*i("ForBody")),["ForStat"]=ca("for")*(i("ForNum")+i("ForGen"))*ca("end"),["RepeatStat"]=da("Repeat",ca("repeat")*i("Block")*ca("until")*i("Expr")),["FuncName"]=n(i("Id")*(ba(".")*da("String",Z(i("Name"),"Name")))^0, function(sa,ta) if ta then return {["tag"]="Index",["pos"]=sa.pos,[1]=sa,[2]=ta} end return sa end )*(ba(":")*da("String",Z(i("Name"),"Name")))^(-1)/ function(sa,ta) if ta then return {["tag"]="Index",["pos"]=sa.pos,["is_method"]=true,[1]=sa,[2]=ta} end return sa end ,["ParList"]=i("NameList")*(ba(",")*ba("...")*da("Dots",q()))^(-1)/ function(R,ua) if ua then table.insert(R,ua) end return R end +ba("...")*da("Dots",q())/ function(ua) return {ua} end +g(true)/ function() return {} end ,["FuncBody"]=da("Function",ba("(")*i("ParList")*ba(")")*i("Block")*ca("end")),["FuncStat"]=da("Set",ca("function")*i("FuncName")*i("FuncBody"))/ function(R) if R[1].is_method then table.insert(R[2][1],1,{["tag"]="Id",[1]="self"}) end R[1]={R[1]};R[2]={R[2]}; return R end ,["LocalFunc"]=da("Localrec",ca("function")*i("Id")*i("FuncBody"))/ function(R)R[1]={R[1]};R[2]={R[2]}; return R end ,["LocalAssign"]=da("Local",i("NameList")*((ba("=")*i("ExpList"))+r(m()))),["LocalStat"]=ca("local")*(i("LocalFunc")+i("LocalAssign")),["LabelStat"]=da("Label",ba("::")*Z(i("Name"),"Name")*ba("::")),["BreakStat"]=da("Break",ca("break")),["ContinueStat"]=da("Continue",ca("continue")),["GoToStat"]=da("Goto",ca("goto")*Z(i("Name"),"Name")),["RetStat"]=da("Return",ca("return")*(i("Expr")*(ba(",")*i("Expr"))^0)^(-1)*ba(";")^(-1)),["ExprStat"]=p((i("SuffixedExp")*(m( function()local va={...};local wa=va[#va];table.remove(va) for xa,ua in ipairs(va) do if ua.tag=="Id" or ua.tag=="Index" then va[xa]=ua; else return false end end va.tag="VarList";va.pos=va[1].pos; return true,{["tag"]="Set",["pos"]=va.pos,[1]=va,[2]=wa} end )*i("Assignment")))+(i("SuffixedExp")*(m( function(P) if P.tag=="Call" or P.tag=="Invoke" then return true,P end return false end ))), function(P,Q,va,wa,...) return wa(va,...) end ),["Assignment"]=((ba(",")*i("SuffixedExp"))^1)^(-1)*ba("=")*i("ExpList"),["Stat"]=i("IfStat")+i("WhileStat")+i("DoStat")+i("ForStat")+i("RepeatStat")+i("FuncStat")+i("LocalStat")+i("LabelStat")+i("BreakStat")+i("GoToStat")+i("ExprStat")+i("ContinueStat"),["Space"]=w^1,["Equals"]=g("=")^0,["Open"]="["*o(i("Equals"),"init")*"["*g("\n")^(-1),["Close"]="]"*j(i("Equals"))*"]",["CloseEQ"]=p(i("Close")*l("init"), function(P,Q,na,xa) return na==xa end ),["LongString"]=i("Open")*j((g(1)-i("CloseEQ"))^0)*i("Close")/ function(P,ya) return P end ,["Comment"]=g("--")*i("LongString")/ function() return end +g("--")*(g(1)-g("\n"))^0+g("//")*(g(1)-g("\n"))^0+j(J)/ function() return end ,["Skip"]=(i("Space")+i("Comment"))^0,["idStart"]=s+g("_"),["idRest"]=u+g("_"),["Keywords"]=g("and")+"break"+"do"+"elseif"+"else"+"end"+"false"+"for"+"function"+"goto"+"if"+"in"+"local"+"nil"+"not"+"or"+"repeat"+"return"+"then"+"true"+"until"+"while"+"continue",["Reserved"]=i("Keywords")*-i("idRest"),["Identifier"]=i("idStart")*i("idRest")^0,["Name"]=-i("Reserved")*j(i("Identifier"))*-i("idRest"),["Hex"]=(g("0x")+g("0X"))*v^1,["Expo"]=h("eE")*h("+-")^(-1)*t^1,["Float"]=(((t^1*g(".")*t^0)+(g(".")*t^1))*i("Expo")^(-1))+(t^1*i("Expo")),["Int"]=t^1,["Number"]=j(i("Hex")+i("Float")+i("Int"))/ function(W) return tonumber(W) end ,["ShortString"]=g("\"")*j(((g("\\")*g(1))+(g(1)-g("\"")))^0)*g("\"")+g("\'")*j(((g("\\")*g(1))+(g(1)-g("\'")))^0)*g("\'"),["String"]=i("LongString")+(i("ShortString")/ function(P) return c(P) end ),["OrOp"]=ca("or")/"or"+ba("||")/"or",["AndOp"]=ca("and")/"and"+ba("&&")/"and",["RelOp"]=ba("~=")/"ne"+ba("==")/"eq"+ba("<=")/"le"+ba(">=")/"ge"+ba("<")/"lt"+ba(">")/"gt"+ba("!=")/"ne",["BOrOp"]=ba("|")/"bor",["BXorOp"]=ba("~")/"bxor",["BAndOp"]=ba("&")/"band",["ShiftOp"]=ba("<<")/"shl"+ba(">>")/"shr",["ConOp"]=ba("..")/"concat",["AddOp"]=ba("+")/"add"+ba("-")/"sub",["MulOp"]=ba("*")/"mul"+ba("/")/"div"+ba("%")/"mod",["UnOp"]=ca("not")/"not"+ba("-")/"unm"+ba("#")/"len"+ba("~")/"bnot"+ba("!")/"not",["PowOp"]=ba("^")/"pow",["Shebang"]=g("#")*(g(1)-g("\n"))^0*g("\n"),["OneWord"]=i("Name")+i("Number")+i("String")+i("Reserved")+g("...")+g(1)}; local function za(Aa,f,Ba)local Ca=Ba[1]; for P=f,0,-1 do if Aa[P].label[Ca] then return true end end return false end local function Ca(Aa,Da,M)local f=Aa.scope;local Ea=Aa[f].label[Da]; if not Ea then Aa[f].label[Da]={["name"]=Da,["pos"]=M}; return true else local N="label \'%s\' already defined at line %d";local Fa=x(Aa.errorinfo.subject,Ea.pos);N=string.format(N,Da,Fa); return nil,K(Aa.errorinfo,M,N) end end local function Ea(Aa,Ba)local f=Aa.scope;table.insert(Aa[f].goto,Ba) return true end local function Fa(Aa) for P=Aa.maxscope,0,-1 do for Ga,ua in ipairs(Aa[P].goto) do if not za(Aa,P,ua) then local N="no visible label \'%s\' for <goto>";N=string.format(N,ua[1]); return nil,K(Aa.errorinfo,ua.pos,N) end end end return true end local function Ga(Aa,Ha)Aa.function[Aa.fscope].is_vararg=Ha; end local Ia,Ja,Kalocal La,Ma,Na,OaOa= function(Aa,Pa)local Qa=#Pa;local Ha=false; if 0<Qa and Pa[Qa].tag=="Dots" then Ha=true; end Ga(Aa,Ha) return true end ; local function Qa(Aa,Ra)A(Aa)y(Aa)local Sa,N=Oa(Aa,Ra[1]); if not Sa then return Sa,N end Sa,N,Sa,N=La(Aa,Ra[2]); if not Sa then return Sa,N end z(Aa)B(Aa) return true end local function Sa(Aa,Ra)local Ta,N=Ja(Aa,Ra[2]); if not Ta then return Ta,N end if Ra[3] then Ta,N,Ta,N=Ja(Aa,Ra[3]); if not Ta then return Ta,N end end return true end local function Ta(Aa,Ra)local Ua,N=Ja(Aa,Ra[1]); if not Ua then return Ua,N end return true end local function Ua(Aa,Va) for Wa,ua in ipairs(Va) do local ea=ua.tag; if ea=="Pair" then local Xa,N=Ja(Aa,ua[1]); if not Xa then return Xa,N end Xa,N,Xa,N=Ja(Aa,ua[2]); if not Xa then return Xa,N end else local Xa,N=Ja(Aa,ua); if not Xa then return Xa,N end end end return true end local function Wa(Aa,Ra) if not Aa.function[Aa.fscope].is_vararg then local N="cannot use \'...\' outside a vararg function"; return nil,K(Aa.errorinfo,Ra.pos,N) end return true end local function Xa(Aa,Ya)local Za,N=Ja(Aa,Ya[1]); if not Za then return Za,N end for Q=2,#Ya do Za,N,Za,N=Ja(Aa,Ya[Q]); if not Za then return Za,N end end return true end local function Za(Aa,ab)local bb,N=Ja(Aa,ab[1]); if not bb then return bb,N end for Q=3,#ab do bb,N,bb,N=Ja(Aa,ab[Q]); if not bb then return bb,N end end return true end local function bb(Aa,Ba)local cb,N=Na(Aa,Ba[1]); if not cb then return cb,N end cb,N,cb,N=Ma(Aa,Ba[2]); if not cb then return cb,N end return true end local function cb(Aa,Ba) if not E(Aa) then local N="<break> not inside a loop"; return nil,K(Aa.errorinfo,Ba.pos,N) end return true end local function db(Aa,Ba) if not E(Aa) then local N="<continue> not inside a loop"; return nil,K(Aa.errorinfo,Ba.pos,N) end return true end local function eb(Aa,Ba)C(Aa)y(Aa)local fb,N=Ma(Aa,Ba[2]); if not fb then return fb,N end fb,N,fb,N=La(Aa,Ba[3]); if not fb then return fb,N end z(Aa)D(Aa) return true end local function fb(Aa,Ba)local gb,NC(Aa)y(Aa)gb,N,gb,N=Ja(Aa,Ba[2]); if not gb then return gb,N end gb,N,gb,N=Ja(Aa,Ba[3]); if not gb then return gb,N end if Ba[5] then gb,N,gb,N=Ja(Aa,Ba[4]); if not gb then return gb,N end gb,N,gb,N=La(Aa,Ba[5]); if not gb then return gb,N end else gb,N,gb,N=La(Aa,Ba[4]); if not gb then return gb,N end end z(Aa)D(Aa) return true end local function gb(Aa,Ba)local hb,N=Ea(Aa,Ba); if not hb then return hb,N end return true end local function hb(Aa,Ba)local ib=#Ba; if ib%2==0 then for Q=1,ib,2 do local jb,N=Ja(Aa,Ba[Q]); if not jb then return jb,N end jb,N,jb,N=La(Aa,Ba[Q+1]); if not jb then return jb,N end end else for Q=1,ib-1,2 do local jb,N=Ja(Aa,Ba[Q]); if not jb then return jb,N end jb,N,jb,N=La(Aa,Ba[Q+1]); if not jb then return jb,N end end local jb,N=La(Aa,Ba[ib]); if not jb then return jb,N end end return true end local function ib(Aa,Ba)local jb,N=Ca(Aa,Ba[1],Ba.pos); if not jb then return jb,N end return true end local function jb(Aa,Ba)local kb,N=Ma(Aa,Ba[2]); if not kb then return kb,N end return true end local function kb(Aa,Ba)local lb,N=Ja(Aa,Ba[2][1]); if not lb then return lb,N end return true end local function lb(Aa,Ba)C(Aa)local mb,N=La(Aa,Ba[1]); if not mb then return mb,N end mb,N,mb,N=Ja(Aa,Ba[2]); if not mb then return mb,N end D(Aa) return true end local function mb(Aa,Ba)local nb,N=Ma(Aa,Ba); if not nb then return nb,N end return true end local function nb(Aa,Ba)C(Aa)local ob,N=Ja(Aa,Ba[1]); if not ob then return ob,N end ob,N,ob,N=La(Aa,Ba[2]); if not ob then return ob,N end D(Aa) return true end Ka= function(Aa,ob)local ea=ob.tag; if ea=="Id" then return true elseif ea=="Index" then local pb,N=Ja(Aa,ob[1]); if not pb then return pb,N end pb,N,pb,N=Ja(Aa,ob[2]); if not pb then return pb,N end return true else error("expecting a variable, but got a "..ea) end end ;Na= function(Aa,pb) for qb,ua in ipairs(pb) do local rb,N=Ka(Aa,ua); if not rb then return rb,N end end return true end ;Ja= function(Aa,Ra)local ea=Ra.tag; if ea=="Nil" or ea=="True" or ea=="False" or ea=="Number" or ea=="String" then return true elseif ea=="Dots" then return Wa(Aa,Ra) elseif ea=="Function" then return Qa(Aa,Ra) elseif ea=="Table" then return Ua(Aa,Ra) elseif ea=="Op" then return Sa(Aa,Ra) elseif ea=="Paren" then return Ta(Aa,Ra) elseif ea=="Call" then return Xa(Aa,Ra) elseif ea=="Invoke" then return Za(Aa,Ra) elseif ea=="Id" or ea=="Index" then return Ka(Aa,Ra) else error("expecting an expression, but got a "..ea) end end ;Ma= function(Aa,qb) for rb,ua in ipairs(qb) do local sb,N=Ja(Aa,ua); if not sb then return sb,N end end return true end ;Ia= function(Aa,Ba)local ea=Ba.tag; if ea=="Do" then return La(Aa,Ba) elseif ea=="Set" then return bb(Aa,Ba) elseif ea=="While" then return nb(Aa,Ba) elseif ea=="Repeat" then return lb(Aa,Ba) elseif ea=="If" then return hb(Aa,Ba) elseif ea=="Fornum" then return fb(Aa,Ba) elseif ea=="Forin" then return eb(Aa,Ba) elseif ea=="Local" then return jb(Aa,Ba) elseif ea=="Localrec" then return kb(Aa,Ba) elseif ea=="Goto" then return gb(Aa,Ba) elseif ea=="Label" then return ib(Aa,Ba) elseif ea=="Return" then return mb(Aa,Ba) elseif ea=="Break" then return cb(Aa,Ba) elseif ea=="Continue" then return db(Aa,Ba) elseif ea=="Call" then return Xa(Aa,Ba) elseif ea=="Invoke" then return Za(Aa,Ba) else error("expecting a statement, but got a "..ea) end end ;La= function(Aa,rb)local sb={};y(Aa) for tb,ua in ipairs(rb) do local ub,N=Ia(Aa,ua); if not ub then return ub,N end end z(Aa) return true end ; local function sb(tb,L)assert(type(tb)=="table")assert(type(L)=="table")local Aa={["errorinfo"]=L,["function"]={}};A(Aa)Ga(Aa,true)local ub,N=La(Aa,tb); if not ub then return ub,N end B(Aa)ub,N,ub,N=Fa(Aa); if not ub then return ub,N end return tb end d.parse= function(ub,vb)local L={["subject"]=ub,["filename"]=vb};local tb,wb=e.match(ra,ub,nil,L); if not tb then return tb,wb end return sb(tb,L) end ; return d end ;d=d();local e=require("lpeg");e.locale(e)local f={}; local function g(h)local i=type(h);local j if i=="table" then j={}; for k,l in next,h,nil do j[g(k)]=g(l); end setmetatable(j,g(getmetatable(h))) else j=h; end return j end local i={"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 j={}; for k,l in ipairs(i) do j[l]=true; end local k="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY"; local function l(m)local n=string.find(m,"["..k.."]");local o=string.len(m); if n==nil then return string.rep("a",o+1) else local p=string.byte(m,n);local q=string.char(p+(p<122 and 1 or -57));local r=string.sub(m,n+1,o);local s=string.rep("a",n-1);local t=s..q..r; while j[t] or _G[t] do t=l(t); end return t end end local function n(o,p)p=p or 0; for q,r in pairs(o) do for s=0,p do io.write("\t") end io.write(q..":") if type(r)=="table" then io.write("\n")n(r,p+1) else io.write(tostring(r).."\n") end end end local q={}; local function r(s,o) if not q[s.tag]==nil then return q[s.tag](s,o) else error("Attempted to use unknown tag type:"..s.tag) end end q={["Call"]= function(s,o)local t=r(s[1],o);local u={};local v=2; while not s[v]==nil do u[v-1]=r(s[v],o);v=v+1; end local w=table.concat(u,",");local x=table.concat({t,"(",w,")"}); return x end ,["Invoke"]= function(s,o)local t=r(s[1],o);local u={}; for v=3,#s do u[#u+1]=r(s[v],o); end local w=t;local x if s[2].tag=="String" and #s[2][1]<(#t+2) then x=s[2][1];w=w..":"..x.."("; else x=r(s[2],o);w=w.."["..x.."]("..t..","; end w=w..table.concat(u,",");w=w..")"; return w end ,["String"]= function(s,o) if o.strings[s[1]]==nil then local t=a(s[1]);local u=string.format("\"%s\"",t);print("Returning "..u.." from "..s[1].." out of "..t) return u end return o.strings[s[1]] end ,["Id"]= function(s,o) if o.ids[s[1]]==nil then return s[1] end return o.ids[s[1]] end ,["Index"]= function(s,o)local t=r(s[1],o); if s[2].tag=="String" then return table.concat({t,".",s[2][1]}) end return table.concat({t,"[",r(s[2],o),"]"}) end ,["Paren"]= function(s,o) return table.concat({"("..r(s[1],o)..")"}) end ,["Dots"]= function(s,o) return "..." end ,["Forin"]= function(s,o)local t=g(o);local u=r(s[1],t);local v=r(s[2],t);local w=r(s[3],t);local x=table.concat({" for ",u," in ",v," do ",w," end "}); return x end ,["NameList"]= function(s,o)local t={}; for u=1,#s do if not s[u].tag=="Id" then t[#t+1]=r(s[u]); else if not o.ids[s[u][1]]==nil then t[#t+1]=o.ids[s[u][1]]; else local v=l(o.lname);o.lname=v;o.ids[s[u][1]]=v;t[#t+1]=v; end end end local v=table.concat(t,","); return v end ,["ExpList"]= function(s,o)local t={}; for u=1,#s do t[#t+1]=r(s[u],o); end return table.concat(t,",") end ,["Nil"]= function(s,o) return "nil" end ,["True"]= function(s,o) return "true" end ,["False"]= function(s,o) return "false" end ,["Return"]= function(s,o)local t={}; for u,v in ipairs(s) do t[u]=r(v,o); end return " return "..table.concat(t,",") end ,["If"]= function(s,o)local t=r(s[1],o);local u=r(s[2],o);local v={};v[#v+1]=table.concat({" if ",t," then ",u}); for w=3,#s-1,2 do local x=r(s[w],o);local y=r(s[w+1],o);v[#v+1]=table.concat({" elseif ",x," then ",y}); end if #s%2==1 then local x=r(s[#s],o);v[#v+1]=" else "..x; end v[#v+1]=" end "; return table.concat(v) end ,["Fornum"]= function(s,o)local t if s[1].tag=="Id" then if not o.ids[s[1][1]]==nil then t=o.ids[s[1][1]]; else local u=l(o.lname);o.lname=u;o.ids[s[1][1]]=u;t=u; end else t=r(s[1],o); end local u=r(s[2],o);local v=r(s[3],o);local w=1;local x=""; if not s[4].tag=="Block" then w=r(s[4],o);x=r(s[5],o); else x=r(s[4],o); end local y= not w==1 and (","..w) or "";o[t]=nil; return table.concat({" for ",t,"=",u,",",v,y," do ",x," end "}) end ,["Op"]= function(s,o)local t={["or"]=" or ",["and"]=" and ",["ne"]="~=",["eq"]="==",["le"]="<=",["ge"]=">=",["lt"]="<",["gt"]=">",["bor"]="|",["bxor"]="~",["band"]="&",["shl"]="<<",["shr"]=">>",["concat"]="..",["add"]="+",["sub"]="-",["mul"]="*",["div"]="/",["mod"]="%",["pow"]="^"};local u={["len"]="#",["not"]=" not ",["unm"]="-",["bnot"]="~"};local v=s[1]; if not u[v]==nil then local w=r(s[2],o); return u[v]..w end local w=r(s[2],o);local x=r(s[3],o);local y=table.concat({w,t[v],x}); return y end ,["Pair"]= function(s,o)local t=r(s[1],o);local u=r(s[2],o); return table.concat({"[",t,"]=",u}) end ,["Table"]= function(s,o)local t={}; for u=1,#s do t[#t+1]=r(s[u],o); end local v=table.concat(t,","); return table.concat({"{",v,"}"}) end ,["Number"]= function(s,o) return s[1] end ,["Local"]= function(s,o)local t=o;local u,v=r(s[1],t),nil; if not s[2].tag==nil then v=r(s[2],t); end local w="local "..u; if not s[2].tag==nil then w=w.."="..v..";"; end return w end ,["VarList"]= function(s,o)local t={}; for u=1,#s do t[#t+1]=r(s[u],o); end return table.concat(t,",") end ,["Set"]= function(s,o)local t={};local u= not s[1].tag==nil and s[1] or s[1][1]; for v=1,#s[1] do t[#t+1]=r(u,o); end local w={};local x= not s[2].tag==nil and s[2] or s[2][1]; for v=1,#s[2] do w[#w+1]=r(x,o); end local y=table.concat(t,",");y=y.."="..table.concat(w,","); return y..";" end ,["Label"]= function(s,o) if o.nids[s[1]]==nil then local t=l(o.lname);o.lname=t;o.nids[s[1]]=t; end return "::"..o.nids[s[1]].."::" end ,["Goto"]= function(s,o) if o.nids[s[1]]==nil then local t=l(o.lname);o.lname=t;o.nids[s[1]]=t; end return " goto "..o.nids[s[1]] end ,["Function"]= function(s,o)local t= not s[1].tag==nil and r(s[1],o) or "";local u=r(s[2],o); return table.concat({" function(",t,")",u," end "}) end ,["Localrec"]= function(s,o)local t if not o.ids[s[1][1]]==nil then t=o.ids[s[1][1]]; else local u=l(o.lname);o.lname=u;o.ids[s[1][1][1]]=u;t=u; end local u= not s[2][1][1].tag==nil and r(s[2][1][1],o) or "";local v=r(s[2][1][2],o); return table.concat({" local function ",t,"(",u,")",v," end "}) end ,["Continue"]= function(s,o) return " continue " end ,["While"]= function(s,o)local t=r(s[1],o);local u=r(s[2],o);local v=table.concat({" while ",t," do ",u," end "}); return v end ,["Break"]= function(s,o) return " break " end ,["Block"]= function(s,t)local o=g(t);t.block=true;local u={}; for v=1,#s do u[#u+1]=r(s[v],o); end local w=table.concat(u);local x,y={},{}; for v,z in pairs(o.strings) do if not t.strings[v]==o.strings[v] then x[#x+1]=z;y[#y+1]=string.format("%q",v); end end local z="";local A=" local "..table.concat(x,",");local B=table.concat(y,","); if 0<string.len(B) then z=table.concat({A,"=",B,";"}); end return z..w end }; local function u(b)local v={{"%s*%)%s*","%)"},{"%s*%(%s*","%("},{"%s*;%s*",";"},{"%s*,%s*",","},{";+",";"},{"^%s*",""},{"%s*$",""},{"%s+"," "}}; for w,x in ipairs(v) do b=string.gsub(b,x[1],x[2]); end return b end local function v(b) end f.minify= function(b,w)w=w or "anonymous";local s,x=d.parse(b,w); if not s then error(x) end local y={["strings"]={},["ids"]={},["lname"]="",["nids"]={}}; return r(s,y) end ; return f diff --git a/test/glum_test.lua b/test/glum_test.lua index 3b8e70f..cc19620 100644 --- a/test/glum_test.lua +++ b/test/glum_test.lua @@ -1,3 +1,5 @@ + +print("Hello, from glum_test.lua") local glum = dofile("../src/glum.lua") local str1 = [[ --This is a test @@ -193,12 +195,55 @@ return fuzzel ]] local str4 = [[ ---Fixing that wierd problem with local functions -local blah = "something" -global[blah](global,1) -global:lol(1) +local function safe_str (str) + str = string.gsub(str,"\\", "\\\\") + str = string.gsub(str,"\a", "\\a") + str = string.gsub(str,"\b", "\\b") + str = string.gsub(str,"\f", "\\f") + str = string.gsub(str,"\n", "\\n") + str = string.gsub(str,"\r", "\\r") + str = string.gsub(str,"\t", "\\t") + str = string.gsub(str,"\v", "\\v") + str = string.gsub(str,"\'", "\\'") + str = string.gsub(str,"\"", "\\\"") + return str +end +]] + +local str6 = [[ +local function findsomenewcharacters(str) + for character in string.gmatch(str,".") do + if character == "\n\\t\n" then + print("I found a newline!") + end + end +end +]] +--[[ +local function a(b) + b = string.gsub(b, "\\", "\\\\") + b = string.gsub(b, "\7", "\\\7") + b = string.gsub(b, "\8", "\\\8") + b = string.gsub(b, "\12", "\\\12") + b = string.gsub(b, "\10", "\10") + b = string.gsub(b, "\13", "\10") + b = string.gsub(b, "\9", "\\\9") + b = string.gsub(b, "\11", "\\\11") + b = string.gsub(b, "\'", "\\\'") + b = string.gsub(b, "\"", "\\\"") + + return b +end ]] -local f = glum.minify(str4) + +local f5 = io.open("../src/glum.lua", "r") +local str5 = f5:read("*a") +f5:close() + +print("Glum:") +print(glum) +print(glum.minify) +local f = glum.minify(str5) print(f) --[[ local fuzzel = loadstring(f)() |
