[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: table output
- From: Tony Finch <dot@...>
- Date: Wed, 11 Nov 2009 17:54:34 +0000
On Wed, 11 Nov 2009, Philippe Lhoste wrote:
>
> It is an interesting exercise, not too hard to do (apparently) although
> delicate to do correctly. Since everybody is showing off their
> serializer in this thread, I will show mine! :-D
I feel like joining in. This one is designed to be brief, while handling
arbitrary recursion in keys or values, plus some support for functions.
Its output isn't particularly short or readable.
This code would be a line shorter if I could use ("%q"):format instead of
the gsub() business, but sadly %q doesn't quote thoroughly enough to
safely print a serialized function to a terminal.
local szt = {}
local function char(c) return ("\\%3d"):format(c:byte()) end
local function szstr(s) return ('"%s"'):format(s:gsub("[^ !#-~]", char)) end
local function szfun(f) return "loadstring"..szstr(string.dump(f)) end
local function szany(...) return szt[type(...)](...) end
local function sztbl(t,code,var)
for k,v in pairs(t) do
local ks = szany(k,code,var)
local vs = szany(v,code,var)
code[#code+1] = ("%s[%s]=%s"):format(var[t],ks,vs)
end
return "{}"
end
local function memo(sz)
return function(d,code,var)
if var[d] == nil then
var[1] = var[1] + 1
var[d] = ("_[%d]"):format(var[1])
local index = #code+1
code[index] = "" -- reserve place during recursion
code[index] = ("%s=%s"):format(var[d],sz(d,code,var))
end
return var[d]
end
end
szt["nil"] = tostring
szt["boolean"] = tostring
szt["number"] = tostring
szt["string"] = szstr
szt["function"] = memo(szfun)
szt["table"] = memo(sztbl)
function serialize(d)
local code = { "local _ = {}" }
local value = szany(d,code,{0})
code[#code+1] = "return "..value
if #code == 2 then return code[2]
else return table.concat(code, "\n")
end
end
Tony.
--
f.anthony.n.finch <dot@dotat.at> http://dotat.at/
GERMAN BIGHT HUMBER: SOUTHWEST 5 TO 7. MODERATE OR ROUGH. SQUALLY SHOWERS.
MODERATE OR GOOD.