Add print

This commit is contained in:
Anton Medvedev
2018-07-14 22:43:51 +03:00
parent 14320a1134
commit 3bf88d09ba
2 changed files with 148 additions and 0 deletions
+109
View File
@@ -0,0 +1,109 @@
package expr
import (
"fmt"
"strconv"
)
func (n nilNode) String() string {
return "nil"
}
func (n identifierNode) String() string {
return n.value
}
func (n numberNode) String() string {
return fmt.Sprintf("%v", n.value)
}
func (n boolNode) String() string {
if n.value {
return "true"
}
return "false"
}
func (n textNode) String() string {
return strconv.Quote(n.value)
}
func (n nameNode) String() string {
return n.name
}
func (n unaryNode) String() string {
switch n.operator {
case "!", "not":
return fmt.Sprintf("%v %v", n.operator, n.node)
}
return fmt.Sprintf("%v%v", n.operator, n.node)
}
func (n binaryNode) String() string {
return fmt.Sprintf("%v %v %v", n.left, n.operator, n.right)
}
func (n propertyNode) String() string {
switch n.property.(type) {
case identifierNode:
return fmt.Sprintf("%v.%v", n.node, n.property)
}
return fmt.Sprintf("%v[%v]", n.node, n.property)
}
func (n methodNode) String() string {
s := fmt.Sprintf("%v.%v(", n.node, n.property)
for i, a := range n.arguments {
if i != 0 {
s += ", "
}
s += fmt.Sprintf("%v", a)
}
return s + ")"
}
func (n functionNode) String() string {
s := fmt.Sprintf("%v(", n.name)
for i, a := range n.arguments {
if i != 0 {
s += ", "
}
s += fmt.Sprintf("%v", a)
}
return s + ")"
}
func (n conditionalNode) String() string {
return fmt.Sprintf("%v ? %v : %v", n.cond, n.exp1, n.exp2)
}
func (n arrayNode) String() string {
s := "["
for i, n := range n.nodes {
if i != 0 {
s += ", "
}
s += fmt.Sprintf("%v", n)
}
return s + "]"
}
func (n mapNode) String() string {
s := "{"
for i, p := range n.pairs {
if i != 0 {
s += ", "
}
s += fmt.Sprintf("%v", p)
}
return s + "}"
}
func (n pairNode) String() string {
switch n.key.(type) {
case binaryNode, unaryNode:
return fmt.Sprintf("(%v): %v", n.key, n.value)
}
return fmt.Sprintf("%q: %v", n.key, n.value)
}
+39
View File
@@ -0,0 +1,39 @@
package expr
import (
"testing"
"fmt"
)
type printTest struct {
input Node
expected string
}
var printTests = []printTest{
{
methodNode{nameNode{"foo"}, identifierNode{"bar"}, []Node{textNode{"arg1"}, numberNode{2}, boolNode{true}}},
`foo.bar("arg1", 2, true)`,
},
{
propertyNode{propertyNode{methodNode{methodNode{nameNode{"foo"}, identifierNode{"bar"}, []Node{}}, identifierNode{"foo"}, []Node{}}, identifierNode{"baz"}}, numberNode{33}},
"foo.bar().foo().baz[33]",
},
{
mapNode{[]pairNode{{identifierNode{"foo"}, numberNode{1}}, {binaryNode{"+", numberNode{1}, numberNode{2}}, numberNode{2}}}},
`{"foo": 1, (1 + 2): 2}`,
},
{
functionNode{"call", []Node{propertyNode{arrayNode{[]Node{numberNode{1}, unaryNode{"not", boolNode{true}}}}, identifierNode{"foo"}}}},
"call([1, not true].foo)",
},
}
func TestPrint(t *testing.T) {
for _, test := range printTests {
actual := fmt.Sprintf("%v", test.input)
if actual != test.expected {
t.Errorf("%s:\ngot\n\t%#v\nexpected\n\t%#v", test.expected, actual, test.expected)
}
}
}