@@ -5,148 +5,147 @@ local max, n = 0, 0
5
5
6
6
for key , value in array do
7
7
if typeof (key ) ~= "number" then return false end
8
- if key <= 0 then return false end
9
- if not isPrimitiveType [typeof (value )] then return false end
8
+ if key <= 0 then return false end
9
+ if not isPrimitiveType [typeof (value )] then return false end
10
10
11
- max = if key > max then key else max
12
- n = n + 1
13
- end
11
+ max = if key > max then key else max
12
+ n = n + 1
14
13
15
- return n == max
14
+ return n == max
16
15
end
17
16
18
17
local function formatValue (value )
19
- if typeof (value ) ~= "string" then
20
- return tostring (value )
21
- end
18
+ if typeof (value ) ~= "string" then
19
+ return tostring (value )
20
+ end
22
21
23
- return string.format ("%q" , value )
22
+ return string.format ("%q" , value )
24
23
end
25
24
26
25
local function formatKey (key , seq )
27
- if seq then return "" end
26
+ if seq then return "" end
28
27
29
- if typeof (key ) ~= "string" then
30
- return `[{tostring (key )}] =`
31
- end
28
+ if typeof (key ) ~= "string" then
29
+ return `[{tostring (key )}] =`
30
+ end
32
31
33
- -- key is a simple identifier
34
- if key :match ("^[%a_][%w_]-$" ) == key then
35
- return `{key } = `
36
- end
32
+ -- key is a simple identifier
33
+ if key :match ("^[%a_][%w_]-$" ) == key then
34
+ return `{key } = `
35
+ end
37
36
38
- return `[{string.format ("%q" , key )}] = `
37
+ return `[{string.format ("%q" , key )}] = `
39
38
end
40
39
41
40
local typeSortOrder = {
42
- ["boolean" ] = 1 ,
43
- ["number" ] = 2 ,
44
- ["string" ] = 3 ,
45
- ["function" ] = 4 ,
46
- ["vector" ] = 5 ,
47
- ["buffer" ] = 6 ,
48
- ["thread" ] = 7 ,
49
- ["table" ] = 8 ,
50
- ["userdata" ] = 9 ,
51
- ["nil" ] = 10 ,
41
+ ["boolean" ] = 1 ,
42
+ ["number" ] = 2 ,
43
+ ["string" ] = 3 ,
44
+ ["function" ] = 4 ,
45
+ ["vector" ] = 5 ,
46
+ ["buffer" ] = 6 ,
47
+ ["thread" ] = 7 ,
48
+ ["table" ] = 8 ,
49
+ ["userdata" ] = 9 ,
50
+ ["nil" ] = 10 ,
52
51
}
53
52
54
53
local function traverseTable (dataTable , tableRef , indent )
55
- local output = ""
56
-
57
- local indentStr = string.rep ("\t " , indent )
58
-
59
- local keys = {}
60
-
61
- for key , value in dataTable do
62
- if isPrimitiveType [typeof (key )] then
63
- keys [# keys + 1 ] = key
64
- end
65
- end
66
-
67
- table.sort (keys , function (a ,b )
68
- local typeofTableA , typeofTableB = typeof (dataTable [a ]), typeof (dataTable [b ])
69
-
70
- if typeofTableA ~= typeofTableB then
71
- return typeSortOrder [typeofTableA ] < typeSortOrder [typeofTableB ]
72
- end
73
-
74
- if typeof (a ) == "number" then
75
- return a < b
76
- end
77
-
78
- return tostring (a ) < tostring (b )
79
- end )
80
-
81
- local inSequence = false
82
- local previousKey = 0
83
-
84
- for idx , key in keys do
85
- if typeof (key ) == "number" and key > 0 and key - 1 == previousKey then
86
- previousKey = key
87
- inSequence = true
88
- else
89
- inSequence = false
90
- end
91
-
92
- local value = dataTable [key ]
93
- if typeof (value ) ~= 'table' then
94
- if isPrimitiveType [typeof (value )] then
95
- output = `{output }{indentStr }{formatKey (key , inSequence )}{formatValue (value )},\n `
96
- end
97
-
98
- continue
99
- end
100
-
101
- -- prevents self-referential tables from looping infinitely
102
- if tableRef [value ] then
103
- continue
104
- end
105
-
106
- tableRef [value ] = true
107
-
108
- local hasItems = false
109
- for key , val in value do
110
- if isPrimitiveType [typeof (key )] and isPrimitiveType [typeof (val )] then
111
- hasItems = true
112
- break
113
- end
114
-
115
- if typeof (val ) == 'table' then
116
- hasItems = true
117
- break
118
- end
119
- end
120
-
121
- if not hasItems then
122
- output = string.format ("%s%s%s{},\n " , output , indentStr , formatKey (key , inSequence ))
123
- continue
124
- end
125
-
126
- if isPrimitiveArray (value ) then -- collapse primitive arrays
127
- output = string.format ("%s%s%s{" , output , indentStr , formatKey (key , inSequence ))
128
-
129
- for index = 1 , # value do
130
- output = output .. formatValue (value [index ])
131
- if index < # value then
132
- output = output .. ", "
133
- end
134
- end
135
-
136
- output = output .. "},\n "
137
- continue
138
- end
139
-
140
- output = string.format ("%s%s%s{\n %s%s},\n " ,
141
- output , indentStr , formatKey (key , inSequence ),
142
- traverseTable (value , tableRef , indent + 1 ), indentStr )
143
-
144
- tableRef [value ] = nil
145
- end
146
-
147
- return output
54
+ local output = ""
55
+
56
+ local indentStr = string.rep ("\t " , indent )
57
+
58
+ local keys = {}
59
+
60
+ for key , value in dataTable do
61
+ if isPrimitiveType [typeof (key )] then
62
+ keys [# keys + 1 ] = key
63
+ end
64
+ end
65
+
66
+ table.sort (keys , function (a ,b )
67
+ local typeofTableA , typeofTableB = typeof (dataTable [a ]), typeof (dataTable [b ])
68
+
69
+ if typeofTableA ~= typeofTableB then
70
+ return typeSortOrder [typeofTableA ] < typeSortOrder [typeofTableB ]
71
+ end
72
+
73
+ if typeof (a ) == "number" then
74
+ return a < b
75
+ end
76
+
77
+ return tostring (a ) < tostring (b )
78
+ end )
79
+
80
+ local inSequence = false
81
+ local previousKey = 0
82
+
83
+ for idx , key in keys do
84
+ if typeof (key ) == "number" and key > 0 and key - 1 == previousKey then
85
+ previousKey = key
86
+ inSequence = true
87
+ else
88
+ inSequence = false
89
+ end
90
+
91
+ local value = dataTable [key ]
92
+ if typeof (value ) ~= 'table' then
93
+ if isPrimitiveType [typeof (value )] then
94
+ output = `{output }{indentStr }{formatKey (key , inSequence )}{formatValue (value )},\n `
95
+ end
96
+
97
+ continue
98
+ end
99
+
100
+ -- prevents self-referential tables from looping infinitely
101
+ if tableRef [value ] then
102
+ continue
103
+ end
104
+
105
+ tableRef [value ] = true
106
+
107
+ local hasItems = false
108
+ for key , val in value do
109
+ if isPrimitiveType [typeof (key )] and isPrimitiveType [typeof (val )] then
110
+ hasItems = true
111
+ break
112
+ end
113
+
114
+ if typeof (val ) == 'table' then
115
+ hasItems = true
116
+ break
117
+ end
118
+ end
119
+
120
+ if not hasItems then
121
+ output = string.format ("%s%s%s{},\n " , output , indentStr , formatKey (key , inSequence ))
122
+ continue
123
+ end
124
+
125
+ if isPrimitiveArray (value ) then -- collapse primitive arrays
126
+ output = string.format ("%s%s%s{" , output , indentStr , formatKey (key , inSequence ))
127
+
128
+ for index = 1 , # value do
129
+ output = output .. formatValue (value [index ])
130
+ if index < # value then
131
+ output = output .. ", "
132
+ end
133
+ end
134
+
135
+ output = output .. "},\n "
136
+ continue
137
+ end
138
+
139
+ output = string.format ("%s%s%s{\n %s%s},\n " ,
140
+ output , indentStr , formatKey (key , inSequence ),
141
+ traverseTable (value , tableRef , indent + 1 ), indentStr )
142
+
143
+ tableRef [value ] = nil
144
+ end
145
+
146
+ return output
148
147
end
149
148
150
149
return function (dataTable )
151
- return "{\n " .. traverseTable (dataTable , {[dataTable ]= true }, 1 ) .. "}"
150
+ return "{\n " .. traverseTable (dataTable , {[dataTable ]= true }, 1 ) .. "}"
152
151
end
0 commit comments