Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
91 lines (79 sloc) 2.66 KB
-- Recursive object dumper, for debugging.
-- (c) 2010 David Manura, MIT License.
local M = {}
-- My own object dumper.
-- Intended for debugging, not serialization, with compact formatting.
-- Robust against recursion.
-- Renders Metalua table tag fields specially {tag=X, ...} --> "`X{...}".
-- On first call, only pass parameter o.
-- CATEGORY: AST debug
local ignore_keys_ = {lineinfo=true}
local norecurse_keys_ = {parent=true, ast=true}
local function dumpstring_key_(k, isseen, newindent)
local ks = type(k) == 'string' and k:match'^[%a_][%w_]*$' and k or
'[' .. M.dumpstring(k, isseen, newindent) .. ']'
return ks
end
local function sort_keys_(a, b)
if type(a) == 'number' and type(b) == 'number' then
return a < b
elseif type(a) == 'number' then
return false
elseif type(b) == 'number' then
return true
elseif type(a) == 'string' and type(b) == 'string' then
return a < b
else
return tostring(a) < tostring(b) -- arbitrary
end
end
function M.dumpstring(o, isseen, indent, key)
isseen = isseen or {}
indent = indent or ''
if type(o) == 'table' then
if isseen[o] or norecurse_keys_[key] then
return (type(o.tag) == 'string' and '`' .. o.tag .. ':' or '') .. tostring(o)
else isseen[o] = true end -- avoid recursion
local used = {}
local tag = o.tag
local s = '{'
if type(o.tag) == 'string' then
s = '`' .. tag .. s; used['tag'] = true
end
local newindent = indent .. ' '
local ks = {}; for k in pairs(o) do ks[#ks+1] = k end
table.sort(ks, sort_keys_)
--for i,k in ipairs(ks) do print ('keys', k) end
local forcenummultiline
for k in pairs(o) do
if type(k) == 'number' and type(o[k]) == 'table' then forcenummultiline = true end
end
-- inline elements
for _,k in ipairs(ks) do
if used[k] then -- skip
elseif ignore_keys_[k] then used[k] = true
elseif (type(k) ~= 'number' or not forcenummultiline) and
type(k) ~= 'table' and (type(o[k]) ~= 'table' or norecurse_keys_[k])
then
s = s .. dumpstring_key_(k, isseen, newindent) .. '=' .. M.dumpstring(o[k], isseen, newindent, k) .. ', '
used[k] = true
end
end
-- elements on separate lines
local done
for _,k in ipairs(ks) do
if not used[k] then
if not done then s = s .. '\n'; done = true end
s = s .. newindent .. dumpstring_key_(k, isseen) .. '=' .. M.dumpstring(o[k], isseen, newindent, k) .. ',\n'
end
end
s = s:gsub(',(%s*)$', '%1')
s = s .. (done and indent or '') .. '}'
return s
elseif type(o) == 'string' then
return string.format('%q', o)
else
return tostring(o)
end
end
return M