Last active
October 29, 2020 21:32
-
-
Save MCJack123/265ac2a61a7ea31b44fad646710e719f to your computer and use it in GitHub Desktop.
Table serializer/minimizer for ComputerCraft supporting recursive tables (also deduplicates table entries)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local deconstruct | |
deconstruct = function(t, values, tables) | |
local retval = { } | |
for k, v in pairs(t) do | |
local id | |
for i, w in ipairs(values) do | |
if v == w or (type(v) == "table" and type(w) == "table" and tables[w[1]] == v) then | |
id = i | |
break | |
end | |
end | |
if not (id) then | |
if v == t then | |
table.insert(tables, v) | |
table.insert(values, { | |
#tables, | |
retval | |
}) | |
id = #values | |
elseif type(v) == "table" then | |
table.insert(tables, v) | |
table.insert(values, { | |
#tables | |
}) | |
local tmp = values[#values] | |
id = deconstruct(v, values, tables) | |
tmp[2] = id | |
else | |
table.insert(values, v) | |
id = #values | |
end | |
end | |
retval[k] = id | |
end | |
return retval | |
end | |
local dedupe_impl | |
dedupe_impl = function(t, values) | |
for k, v in pairs(t) do | |
if type(v) == "table" then | |
local found = false | |
for i, w in ipairs(values) do | |
if type(w) == "table" and v == w[2] then | |
t[k] = i | |
found = true | |
break | |
end | |
end | |
if not (found) then | |
dedupe_impl(v, values) | |
end | |
end | |
end | |
end | |
local dedupe | |
dedupe = function(values) | |
for k, v in ipairs(values) do | |
if type(v) == "table" then | |
dedupe_impl(v[2], values) | |
end | |
end | |
end | |
local search | |
search = function(t, i) | |
for k, v in pairs(t) do | |
if v == i or (type(v) == "table" and search(v, i)) then | |
return true | |
end | |
end | |
return false | |
end | |
local reduce | |
reduce = function(d, v) | |
for i = 1, #v do | |
local found = search(d, i) | |
if not (found) then | |
for j, w in ipairs(v) do | |
if type(w) == "table" then | |
found = search(w[2], i) | |
end | |
if found then | |
break | |
end | |
end | |
end | |
if not (found) then | |
v[i] = 0 | |
end | |
end | |
end | |
local serialize_value_table | |
serialize_value_table = function(t) | |
local retval = "{" | |
for k, v in pairs(t) do | |
retval = retval .. ("[" .. textutils.serialize(k) .. "]=") | |
if type(v) == "table" then | |
retval = retval .. ("function()return" .. serialize_value_table(v .. "end")) | |
else | |
retval = retval .. ("l(" .. v .. ")") | |
end | |
if not (nil == next(t, k)) then | |
retval = retval .. "," | |
end | |
end | |
return retval .. "}" | |
end | |
local serialize_values | |
serialize_values = function(values, min) | |
local retval = "(function() l=function(z)return function()return v[z]end end " | |
if min then | |
retval = retval .. "a=function(t)for k,w in pairs(t)do t[k]=w()end end " | |
end | |
retval = retval .. "v={" | |
for i, v in ipairs(values) do | |
if type(v) == "table" then | |
retval = retval .. serialize_value_table(v[2]) | |
else | |
retval = retval .. textutils.serialize(v) | |
end | |
if not (nil == next(values, i)) then | |
retval = retval .. "," | |
end | |
end | |
return retval .. "}" | |
end | |
local serialize_impl | |
serialize_impl = function(t) | |
local retval = "{" | |
for k, v in pairs(t) do | |
retval = retval .. ("[" .. textutils.serialize(k) .. "]=") | |
if type(v) == "table" then | |
retval = retval .. serialize_impl(v) | |
else | |
retval = retval .. ("v[" .. v .. "]") | |
end | |
if not (nil == next(t, k)) then | |
retval = retval .. "," | |
end | |
end | |
return retval .. "}" | |
end | |
local construct_unpacker | |
construct_unpacker = function(t, min) | |
if min then | |
return "for i=1," .. #t .. " do if(" .. textutils.serialize((function() | |
local _tbl_0 = { } | |
for i, v in ipairs(t) do | |
if type(v) == "table" then | |
_tbl_0[i] = 1 | |
end | |
end | |
return _tbl_0 | |
end)()):gsub("[\n ]", "") .. ")[i]then a(v[i])end end return" | |
else | |
local retval = "" | |
for k, v in ipairs(t) do | |
if type(v) == "table" then | |
for l in pairs(v[2]) do | |
retval = retval .. ("v[" .. k .. "][" .. textutils.serialize(l) .. "]=v[" .. k .. "][" .. textutils.serialize(l) .. "]()") | |
end | |
end | |
end | |
return retval .. "return" | |
end | |
end | |
local serialize | |
serialize = function(t, min) | |
if nil == next(t) then | |
return "{}" | |
end | |
local v, ts = { }, { } | |
local d = deconstruct(t, v, ts) | |
dedupe(v) | |
reduce(d, v) | |
for i, w in ipairs(v) do | |
if type(w) == "table" and w[2] == d then | |
return serialize_values(v, min) .. construct_unpacker(v, min) .. " v[" .. i .. "]end)()" | |
end | |
end | |
return serialize_values(v, min) .. construct_unpacker(v, min) .. serialize_impl(d) .. "end)()" | |
end | |
return serialize |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
deconstruct = (t, values, tables) -> | |
retval = {} | |
for k,v in pairs t | |
local id | |
for i,w in ipairs values | |
if v == w or (type(v) == "table" and type(w) == "table" and tables[w[1]] == v) | |
id = i | |
break | |
unless id | |
if v == t | |
table.insert tables, v | |
table.insert values, {#tables, retval} | |
id = #values | |
elseif type(v) == "table" | |
table.insert tables, v | |
table.insert values, {#tables} | |
tmp = values[#values] | |
id = deconstruct v, values, tables | |
tmp[2] = id | |
else | |
table.insert values, v | |
id = #values | |
retval[k] = id | |
return retval | |
dedupe_impl = (t, values) -> | |
for k,v in pairs t | |
if type(v) == "table" | |
found = false | |
for i,w in ipairs values | |
if type(w) == "table" and v == w[2] | |
t[k] = i | |
found = true | |
break | |
unless found then dedupe_impl v, values | |
dedupe = (values) -> | |
for k,v in ipairs values | |
if type(v) == "table" | |
dedupe_impl v[2], values | |
search = (t, i) -> | |
for k,v in pairs t do if v == i or (type(v) == "table" and search v, i) then return true | |
return false | |
reduce = (d, v) -> | |
for i = 1, #v | |
found = search d, i | |
unless found | |
for j,w in ipairs v | |
if type(w) == "table" then found = search w[2], i | |
break if found | |
v[i] = 0 unless found | |
serialize_value_table = (t) -> | |
retval = "{" | |
for k,v in pairs t | |
retval ..= "[" .. textutils.serialize(k) .. "]=" | |
if type(v) == "table" then retval ..= "function()return" .. serialize_value_table v .. "end" | |
else retval ..= "l(" .. v .. ")" | |
retval ..= "," unless nil == next t, k | |
return retval .. "}" | |
serialize_values = (values, min) -> | |
retval = "(function() l=function(z)return function()return v[z]end end " | |
retval ..= "a=function(t)for k,w in pairs(t)do t[k]=w()end end " if min | |
retval ..= "v={" | |
for i,v in ipairs values | |
if type(v) == "table" then retval ..= serialize_value_table(v[2]) | |
else retval ..= textutils.serialize v | |
retval ..= "," unless nil == next values, i | |
return retval .. "}" | |
serialize_impl = (t) -> | |
retval = "{" | |
for k,v in pairs t | |
retval ..= "[" .. textutils.serialize(k) .. "]=" | |
if type(v) == "table" then retval ..= serialize_impl v | |
else retval ..= "v[" .. v .. "]" | |
retval ..= "," unless nil == next t, k | |
return retval .. "}" | |
construct_unpacker = (t, min) -> | |
if min then "for i=1," .. #t .. " do if(" .. textutils.serialize({i,1 for i,v in ipairs t when type(v) == "table"})\gsub("[\n ]", "") .. ")[i]then a(v[i])end end return" | |
else | |
retval = "" | |
for k,v in ipairs(t) do if type(v) == "table" then for l in pairs(v[2]) do retval ..= "v[" .. k .. "][" .. textutils.serialize(l) .. "]=v[" .. k .. "][" .. textutils.serialize(l) .. "]()" | |
return retval .. "return" | |
serialize = (t, min) -> | |
return "{}" if nil == next t | |
v, ts = {}, {} | |
d = deconstruct t, v, ts | |
dedupe v | |
reduce d, v | |
for i,w in ipairs v | |
if type(w) == "table" and w[2] == d | |
return serialize_values(v, min) .. construct_unpacker(v, min) .. " v[" .. i .. "]end)()" | |
return serialize_values(v, min) .. construct_unpacker(v, min) .. serialize_impl(d) .. "end)()" | |
return serialize |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment