forked from expr-lang/expr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
print.go
122 lines (103 loc) · 2.34 KB
/
print.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
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
package expr
import (
"fmt"
"strconv"
"strings"
)
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 {
if strings.ContainsAny(n.name, " \t\r\n") {
return fmt.Sprintf("`%s`", n.name)
}
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 {
var leftOp, rightOp *info
op := binaryOperators[n.operator]
switch n.left.(type) {
case binaryNode:
v := binaryOperators[n.left.(binaryNode).operator]
leftOp = &v
}
switch n.right.(type) {
case binaryNode:
v := binaryOperators[n.right.(binaryNode).operator]
rightOp = &v
}
l, r := fmt.Sprintf("%v", n.left), fmt.Sprintf("%v", n.right)
if leftOp != nil {
if leftOp.precedence < op.precedence && op.associativity == left {
l = fmt.Sprintf("(%v)", n.left)
} else if leftOp.precedence >= op.precedence && op.associativity == right {
l = fmt.Sprintf("(%v)", n.left)
}
}
if rightOp != nil {
if rightOp.precedence < op.precedence && op.associativity == left {
r = fmt.Sprintf("(%v)", n.right)
} else if rightOp.precedence >= op.precedence && op.associativity == right {
r = fmt.Sprintf("(%v)", n.right)
}
}
return fmt.Sprintf("%v %v %v", l, n.operator, r)
}
func (n matchesNode) String() string {
return fmt.Sprintf("(%v matches %v)", n.left, n.right)
}
func (n builtinNode) 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 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 + "]"
}