.
This commit is contained in:
parent
c76f172975
commit
af75dcc7c5
3 changed files with 74 additions and 26 deletions
13
extra.lua
13
extra.lua
|
@ -1,3 +1,10 @@
|
||||||
|
local insert = table.insert
|
||||||
|
local pairs = pairs
|
||||||
|
local rawget = rawget
|
||||||
|
local sort = table.sort
|
||||||
|
local tostring = tostring
|
||||||
|
local type = type
|
||||||
|
|
||||||
local function strpad(num, count, pad)
|
local function strpad(num, count, pad)
|
||||||
num = tostring(num)
|
num = tostring(num)
|
||||||
return (pad:rep(count)..num):sub(#num)
|
return (pad:rep(count)..num):sub(#num)
|
||||||
|
@ -18,9 +25,9 @@ end
|
||||||
local function order_keys(t)
|
local function order_keys(t)
|
||||||
local oi = {}
|
local oi = {}
|
||||||
for key in pairs(t) do
|
for key in pairs(t) do
|
||||||
table.insert(oi, key)
|
insert(oi, key)
|
||||||
end
|
end
|
||||||
table.sort(oi, mixed_sorter)
|
sort(oi, mixed_sorter)
|
||||||
return oi
|
return oi
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -33,7 +40,7 @@ local function opairs(t, cache)
|
||||||
return function()
|
return function()
|
||||||
i = i + 1
|
i = i + 1
|
||||||
local key = oi[i]
|
local key = oi[i]
|
||||||
if key then return key, t[key] end
|
if key ~= nil then return key, t[key] end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
74
pt.lua
74
pt.lua
|
@ -25,8 +25,8 @@ local function copy(t)
|
||||||
-- shallow copy
|
-- shallow copy
|
||||||
if type(t) ~= 'table' then return end
|
if type(t) ~= 'table' then return end
|
||||||
local new = {}
|
local new = {}
|
||||||
for key, value in pairs(t) do
|
for k,v in pairs(t) do
|
||||||
new[key] = value
|
new[k] = v
|
||||||
end
|
end
|
||||||
return new
|
return new
|
||||||
end
|
end
|
||||||
|
@ -43,7 +43,10 @@ function pt.__call(pt, args)
|
||||||
self.depth = args.depth or 16
|
self.depth = args.depth or 16
|
||||||
self.writer = args.writer or io.write
|
self.writer = args.writer or io.write
|
||||||
self.skeleton = args.skeleton or false
|
self.skeleton = args.skeleton or false
|
||||||
|
self.outer = args.alt_order and self.outer_old or self.outer
|
||||||
|
self.indent = args.indent or ' '
|
||||||
self.queued = {}
|
self.queued = {}
|
||||||
|
self.cache = {}
|
||||||
self:inner('__root__', t, '')
|
self:inner('__root__', t, '')
|
||||||
return self.seen
|
return self.seen
|
||||||
end
|
end
|
||||||
|
@ -61,7 +64,7 @@ function pt.safekey(k)
|
||||||
return s:find('[^%w_]') and ('%q'):format(s) or s
|
return s:find('[^%w_]') and ('%q'):format(s) or s
|
||||||
end
|
end
|
||||||
|
|
||||||
function pt.safeval(v, indent)
|
function pt.safeval(v, indentation, indent)
|
||||||
if type(v) == 'function' then
|
if type(v) == 'function' then
|
||||||
return 'f'..getaddr(v)
|
return 'f'..getaddr(v)
|
||||||
end
|
end
|
||||||
|
@ -69,25 +72,28 @@ function pt.safeval(v, indent)
|
||||||
if type(v) == 'number' then
|
if type(v) == 'number' then
|
||||||
return s
|
return s
|
||||||
end
|
end
|
||||||
s = s:find('[\r\n]') and ('\n'..s):gsub('[\r\n]', '\n'..indent..' ') or s
|
-- TODO: move newline/indentation handling to another function?
|
||||||
|
if s:find('[\r\n]') then
|
||||||
|
s = ('\n'..s):gsub('[\r\n]', '\n'..indentation..indent)
|
||||||
|
end
|
||||||
--local safe = ('%q'):format(s)
|
--local safe = ('%q'):format(s)
|
||||||
--return s == safe:sub(2, -2) and s or safe
|
--return s == safe:sub(2, -2) and s or safe
|
||||||
-- TODO: finish matching valid characters
|
-- TODO: finish matching valid characters
|
||||||
return s:find('[^%w_()[]{}.]') and ('%q'):format(s) or s
|
return s:find('[^%w_()[]{}.]') and ('%q'):format(s) or s
|
||||||
end
|
end
|
||||||
|
|
||||||
function pt:inner(k, v, indent)
|
function pt:inner(k, v, indentation)
|
||||||
if type(v) ~= 'table' then
|
if type(v) ~= 'table' then
|
||||||
if self.skeleton then return end
|
if self.skeleton then return end
|
||||||
self:write(indent, pt.safekey(k), ': ')
|
self:write(indentation, pt.safekey(k), ': ')
|
||||||
self:write(pt.safeval(v, indent), '\n')
|
self:write(pt.safeval(v, indentation, self.indent), '\n')
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local addr = getaddr(v)
|
local addr = getaddr(v)
|
||||||
self:write(indent, pt.safekey(k))
|
self:write(indentation, pt.safekey(k))
|
||||||
|
|
||||||
if #indent > self.depth or self.skipped[addr] then
|
if #indentation > self.depth or self.skipped[addr] then
|
||||||
--self.skipped[addr] = true -- TODO: extra logics
|
--self.skipped[addr] = true -- TODO: extra logics
|
||||||
self:write(': #t', addr, '\n')
|
self:write(': #t', addr, '\n')
|
||||||
return
|
return
|
||||||
|
@ -101,12 +107,13 @@ function pt:inner(k, v, indent)
|
||||||
self.seen[addr] = true
|
self.seen[addr] = true
|
||||||
|
|
||||||
self:write(': &t', addr, '\n')
|
self:write(': &t', addr, '\n')
|
||||||
self:outer(v, indent..' ')
|
self:outer(v, indentation..self.indent)
|
||||||
end
|
end
|
||||||
|
|
||||||
function pt:outer(t, indent)
|
function pt:outer_old(t, indentation)
|
||||||
if type(t) ~= "table" then
|
if type(t) ~= "table" then
|
||||||
self:write(indent, pt.safeval(t, indent), '\n')
|
local s = pt.safeval(t, indentation, self.indent)
|
||||||
|
self:write(indentation, s, '\n')
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -116,29 +123,62 @@ function pt:outer(t, indent)
|
||||||
for k,v in opairs(t) do
|
for k,v in opairs(t) do
|
||||||
if type(v) == 'table' then
|
if type(v) == 'table' then
|
||||||
local addr = getaddr(v)
|
local addr = getaddr(v)
|
||||||
if not self.queued[addr] and not self.seen[addr] and not self.skipped[addr] then
|
if not (self.queued[addr] or self.seen[addr] or self.skipped[addr]) then
|
||||||
self.queued[addr] = true
|
self.queued[addr] = true
|
||||||
ours[k] = v
|
ours[k] = v
|
||||||
else
|
else
|
||||||
not_ours[k] = v
|
not_ours[k] = v
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self:inner(k, v, indent)
|
self:inner(k, v, indentation)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for k,v in opairs(not_ours) do
|
for k,v in opairs(not_ours) do
|
||||||
self:inner(k, v, indent)
|
self:inner(k, v, indentation)
|
||||||
end
|
end
|
||||||
|
|
||||||
for k,v in opairs(ours) do
|
for k,v in opairs(ours) do
|
||||||
self.queued[getaddr(v)] = nil
|
self.queued[getaddr(v)] = nil
|
||||||
self:inner(k, v, indent)
|
self:inner(k, v, indentation)
|
||||||
end
|
end
|
||||||
|
|
||||||
local mt = getmetatable(t)
|
local mt = getmetatable(t)
|
||||||
if mt ~= nil then
|
if mt ~= nil then
|
||||||
self:inner('__metatable', mt, indent)
|
self:inner('__metatable', mt, indentation)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function pt:outer(t, indentation)
|
||||||
|
if type(t) ~= "table" then
|
||||||
|
local s = pt.safeval(t, indentation, self.indent)
|
||||||
|
self:write(indentation, s, '\n')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local ours = {}
|
||||||
|
|
||||||
|
for k,v in opairs(t, self.cache) do
|
||||||
|
if type(v) == 'table' then
|
||||||
|
local addr = getaddr(v)
|
||||||
|
if not (self.queued[addr] or self.seen[addr] or self.skipped[addr]) then
|
||||||
|
self.queued[addr] = true
|
||||||
|
ours[k] = addr
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local mt = getmetatable(t)
|
||||||
|
if mt ~= nil then
|
||||||
|
self:inner('__metatable', mt, indentation)
|
||||||
|
end
|
||||||
|
|
||||||
|
for k,v in opairs(t, self.cache) do
|
||||||
|
local addr = ours[k]
|
||||||
|
if addr then
|
||||||
|
self.queued[addr] = nil
|
||||||
|
end
|
||||||
|
self:inner(k, v, indentation)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
13
run.lua
13
run.lua
|
@ -2,21 +2,22 @@
|
||||||
local pt = require('pt')
|
local pt = require('pt')
|
||||||
|
|
||||||
t = {
|
t = {
|
||||||
A = {
|
A = 'hello',
|
||||||
|
B = {
|
||||||
a = 'beep',
|
a = 'beep',
|
||||||
b = 'boop',
|
b = 'boop',
|
||||||
c = 'burp',
|
c = 'burp',
|
||||||
},
|
},
|
||||||
B = {
|
C = {
|
||||||
a = 'nude',
|
a = 'nude',
|
||||||
b = 'dude',
|
b = 'dude',
|
||||||
c = 'lewd',
|
c = 'lewd',
|
||||||
},
|
},
|
||||||
C = 'hello',
|
D = 'goodbye',
|
||||||
}
|
}
|
||||||
t.A.d = t.B
|
t.B.d = t.C
|
||||||
t.B.d = t.A
|
t.C.d = t.B
|
||||||
t.D = t
|
t.E = t
|
||||||
|
|
||||||
function dump(t, fn, seen)
|
function dump(t, fn, seen)
|
||||||
if t == nil then return end
|
if t == nil then return end
|
||||||
|
|
Loading…
Reference in a new issue