lua-debug-tui/repr.lua
2018-03-21 19:22:30 -07:00

70 lines
2.4 KiB
Lua

local re = require 're'
local _quote_state = {}
local max = math.max
local _quote_patt = re.compile("(({'\n' / '\"' / \"'\" / '\\'}->mark_char) / (']' ({'='*}->mark_eq) (']' / !.)) / .)*",
{mark_char=function(q)
if q == "\n" or q == "\\" then
_quote_state["'"] = false
_quote_state['"'] = false
if _quote_state.min_eq == nil then
_quote_state.min_eq = 0
end
elseif q == "'" then
_quote_state["'"] = false
elseif q == '"' then
_quote_state['"'] = false
end
end,
mark_eq=function(eq)
_quote_state.min_eq = max(_quote_state.min_eq or 0, #eq+1)
end})
local function repr(x, depth)
-- Create a string representation of the object that is close to the lua code that will
-- reproduce the object (similar to Python's "repr" function)
depth = depth or 10
if depth == 0 then return "..." end
depth = depth - 1
local x_type = type(x)
if x_type == 'table' then
local ret = {}
local i = 1
for k, v in pairs(x) do
if k == i then
ret[#ret+1] = repr(x[i], depth)
i = i + 1
elseif type(k) == 'string' and k:match("[_a-zA-Z][_a-zA-Z0-9]*") then
ret[#ret+1] = k.."= "..repr(v,depth)
else
ret[#ret+1] = "["..repr(k,depth).."]= "..repr(v,depth)
end
end
return "{"..table.concat(ret, ", ").."}"
elseif x_type == 'string' then
if x == "\n" then
return "'\\n'"
end
_quote_state = {}
_quote_patt:match(x)
if _quote_state["'"] ~= false then
return "\'" .. x .. "\'"
elseif _quote_state['"'] ~= false then
return "\"" .. x .. "\""
else
local eq = ("="):rep(_quote_state.min_eq or 0)
-- BEWARE!!!
-- Lua's parser and syntax are dumb, so Lua interprets x[[=[asdf]=]] as
-- a function call to x (i.e. x("=[asdf]=")), instead of indexing x
-- (i.e. x["asdf"]), which it obviously should be. This can be fixed by
-- slapping spaces or parens around the [=[asdf]=].
if x:sub(1, 1) == "\n" then
return "["..eq.."[\n"..x.."]"..eq.."]"
else
return "["..eq.."["..x.."]"..eq.."]"
end
end
else
return tostring(x)
end
end
return repr