From 5f55fa294d5e376c60908a4a9eea44a1af2f3636 Mon Sep 17 00:00:00 2001 From: Izaya Date: Thu, 17 May 2018 16:19:04 +1000 Subject: [PATCH] minification can now be done from inside OC --- Embedded/minify.lua | 69 ++++++++++++++++++ Embedded/serialization.lua | 146 +++++++++++++++++++++++++++++++++++++ Embedded/vt100.lua.min | 19 +++++ 3 files changed, 234 insertions(+) create mode 100644 Embedded/minify.lua create mode 100644 Embedded/serialization.lua create mode 100644 Embedded/vt100.lua.min diff --git a/Embedded/minify.lua b/Embedded/minify.lua new file mode 100644 index 0000000..7b2230f --- /dev/null +++ b/Embedded/minify.lua @@ -0,0 +1,69 @@ +local serial = require "serialization" + +local tArgs = {...} +local infile = tArgs[1] +local minfile = tArgs[1]..".min" +local outfile = tArgs[2] +local dbug = true + +local function dprint(...) + if dbug then + print(...) + end +end + +local replacements={ +{" "," "}, +{"\n ","\n"}, +{"\n\n","\n"}, +{" == ","=="}, +{" ~= ","~="}, +{" >= ",">="}, +{" <= ","<="}, +{" > ",">"}, +{" < ","<"}, +{" = ","="}, +{", ",","}, +{" %+ ","+"}, +{" %- ","-"}, +{" %/ ","/"}, +{" %* ","*"}, +{" \n","\n"}, +{"%-%-.-\n",""}, +} + +dprint("Loading replacements...") + +local initr = #replacements + +local fmin = io.open(minfile,"rb") +if fmin then + local nreplacements = serial.unserialize(fmin:read("*a")) + for k,v in ipairs(nreplacements) do + table.insert(replacements,1+k,v) + end +end + +dprint(tostring(#replacements - initr).." replacements loaded.") + +local fin = io.open(infile,"rb") +local ss = fin:read("*a") +fin:close() + +local initl = ss:len() + +for k,v in ipairs(replacements) do + while ss:find(v[1]) ~= nil do + ss=ss:gsub(v[1],v[2]) + end +end + +print("Delta: "..tostring(initl - ss:len()).." bytes") + +if outfile then + local outf = io.open(outfile,"wb") + outf:write(ss) + outf:close() +else +print(ss) +end diff --git a/Embedded/serialization.lua b/Embedded/serialization.lua new file mode 100644 index 0000000..22b6183 --- /dev/null +++ b/Embedded/serialization.lua @@ -0,0 +1,146 @@ +-- Borrowed from OpenOS. + +local serialization = {} + +-- delay loaded tables fail to deserialize cross [C] boundaries (such as when having to read files that cause yields) +local local_pairs = function(tbl) + local mt = getmetatable(tbl) + return (mt and mt.__pairs or pairs)(tbl) +end + +-- Important: pretty formatting will allow presenting non-serializable values +-- but may generate output that cannot be unserialized back. +function serialization.serialize(value, pretty) + local kw = {["and"]=true, ["break"]=true, ["do"]=true, ["else"]=true, + ["elseif"]=true, ["end"]=true, ["false"]=true, ["for"]=true, + ["function"]=true, ["goto"]=true, ["if"]=true, ["in"]=true, + ["local"]=true, ["nil"]=true, ["not"]=true, ["or"]=true, + ["repeat"]=true, ["return"]=true, ["then"]=true, ["true"]=true, + ["until"]=true, ["while"]=true} + local id = "^[%a_][%w_]*$" + local ts = {} + local result_pack = {} + local function recurse(current_value, depth) + local t = type(current_value) + if t == "number" then + if current_value ~= current_value then + table.insert(result_pack, "0/0") + elseif current_value == math.huge then + table.insert(result_pack, "math.huge") + elseif current_value == -math.huge then + table.insert(result_pack, "-math.huge") + else + table.insert(result_pack, tostring(current_value)) + end + elseif t == "string" then + table.insert(result_pack, (string.format("%q", current_value):gsub("\\\n","\\n"))) + elseif + t == "nil" or + t == "boolean" or + pretty and (t ~= "table" or (getmetatable(current_value) or {}).__tostring) then + table.insert(result_pack, tostring(current_value)) + elseif t == "table" then + if ts[current_value] then + if pretty then + table.insert(result_pack, "recursion") + return + else + error("tables with cycles are not supported") + end + end + ts[current_value] = true + local f + if pretty then + local ks, sks, oks = {}, {}, {} + for k in local_pairs(current_value) do + if type(k) == "number" then + table.insert(ks, k) + elseif type(k) == "string" then + table.insert(sks, k) + else + table.insert(oks, k) + end + end + table.sort(ks) + table.sort(sks) + for _, k in ipairs(sks) do + table.insert(ks, k) + end + for _, k in ipairs(oks) do + table.insert(ks, k) + end + local n = 0 + f = table.pack(function() + n = n + 1 + local k = ks[n] + if k ~= nil then + return k, current_value[k] + else + return nil + end + end) + else + f = table.pack(local_pairs(current_value)) + end + local i = 1 + local first = true + table.insert(result_pack, "{") + for k, v in table.unpack(f) do + if not first then + table.insert(result_pack, ",") + if pretty then + table.insert(result_pack, "\n" .. string.rep(" ", depth)) + end + end + first = nil + local tk = type(k) + if tk == "number" and k == i then + i = i + 1 + recurse(v, depth + 1) + else + if tk == "string" and not kw[k] and string.match(k, id) then + table.insert(result_pack, k) + else + table.insert(result_pack, "[") + recurse(k, depth + 1) + table.insert(result_pack, "]") + end + table.insert(result_pack, "=") + recurse(v, depth + 1) + end + end + ts[current_value] = nil -- allow writing same table more than once + table.insert(result_pack, "}") + else + error("unsupported type: " .. t) + end + end + recurse(value, 1) + local result = table.concat(result_pack) + if pretty then + local limit = type(pretty) == "number" and pretty or 10 + local truncate = 0 + while limit > 0 and truncate do + truncate = string.find(result, "\n", truncate + 1, true) + limit = limit - 1 + end + if truncate then + return result:sub(1, truncate) .. "..." + end + end + return result +end + +function serialization.unserialize(data) + local result, reason = load("return " .. data, "=data", nil, {math={huge=math.huge}}) + if not result then + return nil, reason + end + local ok, output = pcall(result) + if not ok then + return nil, output + end + return output +end + +return serialization diff --git a/Embedded/vt100.lua.min b/Embedded/vt100.lua.min new file mode 100644 index 0000000..c017132 --- /dev/null +++ b/Embedded/vt100.lua.min @@ -0,0 +1,19 @@ +{ + {"local cx, cy = 1, 1.+local sx, sy = 1,1",""}, + {"string.byte","B"}, + {"0xFFFFFF","F"}, + {"gpu.setForeground","SF"}, + {"gpu.setBackground","SB"}, + {'local cs %= ""','local cx, cy, pc, lc, mode, lw, sx, sy, cs, B, F, SF, SB = 1, 1, " ", "", "n", true, 1, 1, "", string.byte, 0xFFFFFF, gpu.setForeground, gpu.setBackground'}, + {"gpu","G"}, + {"dcursor","DC"}, + {"termwrite","TW"}, + {"cc","C"}, + {"cs","S"}, + {"cx","X"}, + {"cy","Y"}, + {"mx","W"}, + {"my","H"}, + {"sx","T"}, + {"sy","U"}, +}