Skip to content

Commit 3bf88d0

Browse files
committed
Add print
1 parent 14320a1 commit 3bf88d0

File tree

2 files changed

+148
-0
lines changed

2 files changed

+148
-0
lines changed

print.go

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package expr
2+
3+
import (
4+
"fmt"
5+
"strconv"
6+
)
7+
8+
func (n nilNode) String() string {
9+
return "nil"
10+
}
11+
12+
func (n identifierNode) String() string {
13+
return n.value
14+
}
15+
16+
func (n numberNode) String() string {
17+
return fmt.Sprintf("%v", n.value)
18+
}
19+
20+
func (n boolNode) String() string {
21+
if n.value {
22+
return "true"
23+
}
24+
return "false"
25+
}
26+
27+
func (n textNode) String() string {
28+
return strconv.Quote(n.value)
29+
}
30+
31+
func (n nameNode) String() string {
32+
return n.name
33+
}
34+
35+
func (n unaryNode) String() string {
36+
switch n.operator {
37+
case "!", "not":
38+
return fmt.Sprintf("%v %v", n.operator, n.node)
39+
}
40+
return fmt.Sprintf("%v%v", n.operator, n.node)
41+
}
42+
43+
func (n binaryNode) String() string {
44+
return fmt.Sprintf("%v %v %v", n.left, n.operator, n.right)
45+
}
46+
47+
func (n propertyNode) String() string {
48+
switch n.property.(type) {
49+
case identifierNode:
50+
return fmt.Sprintf("%v.%v", n.node, n.property)
51+
}
52+
return fmt.Sprintf("%v[%v]", n.node, n.property)
53+
}
54+
55+
func (n methodNode) String() string {
56+
s := fmt.Sprintf("%v.%v(", n.node, n.property)
57+
for i, a := range n.arguments {
58+
if i != 0 {
59+
s += ", "
60+
}
61+
s += fmt.Sprintf("%v", a)
62+
}
63+
return s + ")"
64+
}
65+
66+
func (n functionNode) String() string {
67+
s := fmt.Sprintf("%v(", n.name)
68+
for i, a := range n.arguments {
69+
if i != 0 {
70+
s += ", "
71+
}
72+
s += fmt.Sprintf("%v", a)
73+
}
74+
return s + ")"
75+
}
76+
77+
func (n conditionalNode) String() string {
78+
return fmt.Sprintf("%v ? %v : %v", n.cond, n.exp1, n.exp2)
79+
}
80+
81+
func (n arrayNode) String() string {
82+
s := "["
83+
for i, n := range n.nodes {
84+
if i != 0 {
85+
s += ", "
86+
}
87+
s += fmt.Sprintf("%v", n)
88+
}
89+
return s + "]"
90+
}
91+
92+
func (n mapNode) String() string {
93+
s := "{"
94+
for i, p := range n.pairs {
95+
if i != 0 {
96+
s += ", "
97+
}
98+
s += fmt.Sprintf("%v", p)
99+
}
100+
return s + "}"
101+
}
102+
103+
func (n pairNode) String() string {
104+
switch n.key.(type) {
105+
case binaryNode, unaryNode:
106+
return fmt.Sprintf("(%v): %v", n.key, n.value)
107+
}
108+
return fmt.Sprintf("%q: %v", n.key, n.value)
109+
}

print_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package expr
2+
3+
import (
4+
"testing"
5+
"fmt"
6+
)
7+
8+
type printTest struct {
9+
input Node
10+
expected string
11+
}
12+
13+
var printTests = []printTest{
14+
{
15+
methodNode{nameNode{"foo"}, identifierNode{"bar"}, []Node{textNode{"arg1"}, numberNode{2}, boolNode{true}}},
16+
`foo.bar("arg1", 2, true)`,
17+
},
18+
{
19+
propertyNode{propertyNode{methodNode{methodNode{nameNode{"foo"}, identifierNode{"bar"}, []Node{}}, identifierNode{"foo"}, []Node{}}, identifierNode{"baz"}}, numberNode{33}},
20+
"foo.bar().foo().baz[33]",
21+
},
22+
{
23+
mapNode{[]pairNode{{identifierNode{"foo"}, numberNode{1}}, {binaryNode{"+", numberNode{1}, numberNode{2}}, numberNode{2}}}},
24+
`{"foo": 1, (1 + 2): 2}`,
25+
},
26+
{
27+
functionNode{"call", []Node{propertyNode{arrayNode{[]Node{numberNode{1}, unaryNode{"not", boolNode{true}}}}, identifierNode{"foo"}}}},
28+
"call([1, not true].foo)",
29+
},
30+
}
31+
32+
func TestPrint(t *testing.T) {
33+
for _, test := range printTests {
34+
actual := fmt.Sprintf("%v", test.input)
35+
if actual != test.expected {
36+
t.Errorf("%s:\ngot\n\t%#v\nexpected\n\t%#v", test.expected, actual, test.expected)
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)