/
dump.go
94 lines (88 loc) · 1.84 KB
/
dump.go
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
package toml
import (
"fmt"
"sort"
"strings"
)
func Dump(n Node) {
dumpNode(n, 0)
}
func dumpNode(n Node, level int) {
space := strings.Repeat(" ", level*2)
switch x := n.(type) {
case *Option:
value := dumpLiteral(x.value, level+2)
fmt.Printf("%soption(pos: %s, key: %s, value: %s),", space, x.Pos(), x.key.Literal, value)
fmt.Println()
case *Table:
if x.kind == tableArray {
fmt.Printf("%sarray{", space)
fmt.Println()
for _, n := range sortNodes(x.nodes) {
dumpNode(n, level+2)
}
fmt.Printf("%s},", space)
fmt.Println()
} else {
label := x.key.Literal
if label == "" {
label = "default"
}
fmt.Printf("%stable[label=%s, kind=%s, pos= %s]{", space, label, x.kind, x.Pos())
fmt.Println()
for _, n := range sortNodes(x.nodes) {
dumpNode(n, level+2)
}
fmt.Printf("%s},", space)
fmt.Println()
}
}
}
func dumpLiteral(n Node, level int) string {
switch x := n.(type) {
case *Literal:
return x.token.String()
case *Array:
var b strings.Builder
b.WriteString("array")
b.WriteRune(lsquare)
for i, n := range x.nodes {
if i > 0 {
b.WriteRune(comma)
b.WriteRune(space)
}
b.WriteString(dumpLiteral(n, level))
}
b.WriteRune(rsquare)
return b.String()
case *Table:
var b strings.Builder
b.WriteString("inline")
b.WriteRune(lcurly)
for _, n := range x.nodes {
o, ok := n.(*Option)
if !ok {
b.WriteString("???")
} else {
b.WriteString(o.key.Literal)
b.WriteRune(equal)
b.WriteString(dumpLiteral(o.value, level))
}
b.WriteRune(comma)
b.WriteRune(space)
}
b.WriteRune(rcurly)
return b.String()
default:
return "???"
}
}
func sortNodes(nodes []Node) []Node {
ns := make([]Node, len(nodes))
copy(ns, nodes)
sort.Slice(ns, func(i, j int) bool {
pi, pj := ns[i].Pos(), ns[j].Pos()
return pi.Line < pj.Line
})
return ns
}