Skip to content

Instantly share code, notes, and snippets.

@MCJack123
Last active October 29, 2020 21:32
Show Gist options
  • Save MCJack123/265ac2a61a7ea31b44fad646710e719f to your computer and use it in GitHub Desktop.
Save MCJack123/265ac2a61a7ea31b44fad646710e719f to your computer and use it in GitHub Desktop.
Table serializer/minimizer for ComputerCraft supporting recursive tables (also deduplicates table entries)
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
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