1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
local function _0_(str)
return ("\"" .. str:gsub("\"", "\\\"") .. "\"")
end
local quote = _0_
local short_control_char_escapes = ({["\11"] = "\\v", ["\12"] = "\\f", ["\13"] = "\\r", ["\7"] = "\\a", ["\8"] = "\\b", ["\9"] = "\\t", ["\n"] = "\\n"})
local function _1_()
local long = ({})
for i = 0, 31 do
local ch = string.char(i)
local function _2_()
if not short_control_char_escapes[ch] then
short_control_char_escapes[ch] = ("\\" .. i)
long[ch] = ("\\%03d"):format(i)
return nil
end
end
_2_()
end
return long
end
local long_control_char_esapes = _1_()
local function _2_(str)
local str = str:gsub("\\", "\\\\")
local str = str:gsub("(%c)%f[0-9]", long_control_char_esapes)
return str:gsub("%c", short_control_char_escapes)
end
local escape = _2_
local function _3_(k, len)
return ((type(k)) == ("number") and (1) <= (k) and (k) <= (len) and (math.floor(k)) == (k))
end
local sequence_key_3f = _3_
local type_order = ({["function"] = 5, boolean = 2, number = 1, string = 3, table = 4, thread = 7, userdata = 6})
local function _4_(a, b)
local ta = type(a)
local tb = type(b)
if ((ta) == (tb) and (ta) ~= ("boolean") and ((ta) == ("string") or (ta) == ("number"))) then
return (a) < (b)
else
local dta = type_order[a]
local dtb = type_order[b]
if (dta and dtb) then
return (dta) < (dtb)
elseif dta then
return true
elseif dtb then
return false
elseif "else" then
return (ta) < (tb)
end
end
end
local sort_keys = _4_
local function _5_(t)
local len = 1
for i in ipairs(t) do
len = i
end
return len
end
local get_sequence_length = _5_
local function _6_(t)
local keys = ({})
local sequence_length = get_sequence_length(t)
for k in pairs(t) do
local function _7_()
if not sequence_key_3f(k, sequence_length) then
return table.insert(keys, k)
end
end
_7_()
end
table.sort(keys, sort_keys)
return keys, sequence_length
end
local get_nonsequential_keys = _6_
local function recur(t, appearances)
local function _7_()
if (type(t)) == ("table") then
if not appearances[t] then
appearances[t] = 1
for k, v in pairs(t) do
recur(k, appearances)
recur(v, appearances)
end
return nil
end
else
if (t and (t) == (t)) then
appearances[t] = ((appearances[t] or 0) + 1)
return nil
end
end
end
_7_()
return appearances
end
local count_table_appearances = recur
local put_value = nil
local function _7_(self, ...)
for _, v in ipairs(({...})) do
table.insert(self.buffer, v)
end
return nil
end
local puts = _7_
local function _8_(self)
return puts(self, "\n", self.indent:rep(self.level))
end
local tabify = _8_
local function _9_(self, v)
return (self.ids[v]) ~= (nil)
end
local already_visited_3f = _9_
local function _10_(self, v)
local id = self.ids[v]
local function _11_()
if not id then
local tv = type(v)
id = ((self["max-ids"][tv] or 0) + 1)
self["max-ids"][tv] = id
self.ids[v] = id
return nil
end
end
_11_()
return tostring(id)
end
local get_id = _10_
local function _11_(self, t, length)
puts(self, "[")
self.level = (self.level + 1)
for i = 1, length do
puts(self, " ")
put_value(self, t[i])
end
self.level = (self.level - 1)
return puts(self, " ]")
end
local put_sequential_table = _11_
local function _12_(self, k)
if ((type(k)) == ("string") and k:find("^[%w?\\^_`!#$%&*+-./@~:|<=>]+$")) then
return puts(self, ":", k)
else
return put_value(self, k)
end
end
local put_key = _12_
local function _13_(self, t)
puts(self, "{")
self.level = (self.level + 1)
for k, v in pairs(t) do
tabify(self)
put_key(self, k)
puts(self, " ")
put_value(self, v)
end
self.level = (self.level - 1)
tabify(self)
return puts(self, "}")
end
local put_kv_table = _13_
local function _14_(self, t)
if already_visited_3f(self, t) then
return puts(self, "#<table ", get_id(self, t), ">")
elseif (self.level) >= (self.depth) then
return puts(self, "{...}")
elseif "else" then
local non_seq_keys, length = get_nonsequential_keys(t)
local id = get_id(self, t)
if (self.appearances[t]) > (1) then
return puts(self, "#<", id, ">")
elseif ((#non_seq_keys) == (0) and (#t) == (0)) then
return puts(self, "{}")
elseif (#non_seq_keys) == (0) then
return put_sequential_table(self, t, length)
elseif "else" then
return put_kv_table(self, t)
end
end
end
local put_table = _14_
local function _15_(self, v)
local tv = type(v)
if (tv) == ("string") then
return puts(self, quote(escape(v)))
elseif ((tv) == ("number") or (tv) == ("boolean") or (tv) == ("nil")) then
return puts(self, tostring(v))
elseif (tv) == ("table") then
return put_table(self, v)
elseif "else" then
return puts(self, "#<", tv, " ", get_id(self, v), ">")
end
end
put_value = _15_
local function _16_(root, options)
local options = (options or ({}))
local inspector = ({["max-ids"] = ({}), appearances = count_table_appearances(root, ({})), buffer = ({}), depth = (options.depth or 128), ids = ({}), indent = (options.indent or " "), level = 0})
put_value(inspector, root)
return table.concat(inspector.buffer)
end
return _16_
|