github.com/expr-lang/expr@v1.16.9/ast/print.go (about) 1 package ast 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strings" 7 8 "github.com/expr-lang/expr/parser/operator" 9 "github.com/expr-lang/expr/parser/utils" 10 ) 11 12 func (n *NilNode) String() string { 13 return "nil" 14 } 15 16 func (n *IdentifierNode) String() string { 17 return n.Value 18 } 19 20 func (n *IntegerNode) String() string { 21 return fmt.Sprintf("%d", n.Value) 22 } 23 24 func (n *FloatNode) String() string { 25 return fmt.Sprintf("%v", n.Value) 26 } 27 28 func (n *BoolNode) String() string { 29 return fmt.Sprintf("%t", n.Value) 30 } 31 32 func (n *StringNode) String() string { 33 return fmt.Sprintf("%q", n.Value) 34 } 35 36 func (n *ConstantNode) String() string { 37 if n.Value == nil { 38 return "nil" 39 } 40 b, err := json.Marshal(n.Value) 41 if err != nil { 42 panic(err) 43 } 44 return string(b) 45 } 46 47 func (n *UnaryNode) String() string { 48 op := "" 49 if n.Operator == "not" { 50 op = fmt.Sprintf("%s ", n.Operator) 51 } else { 52 op = fmt.Sprintf("%s", n.Operator) 53 } 54 if _, ok := n.Node.(*BinaryNode); ok { 55 return fmt.Sprintf("%s(%s)", op, n.Node.String()) 56 } 57 return fmt.Sprintf("%s%s", op, n.Node.String()) 58 } 59 60 func (n *BinaryNode) String() string { 61 if n.Operator == ".." { 62 return fmt.Sprintf("%s..%s", n.Left, n.Right) 63 } 64 65 var lhs, rhs string 66 var lwrap, rwrap bool 67 68 if lb, ok := n.Left.(*BinaryNode); ok { 69 if operator.Less(lb.Operator, n.Operator) { 70 lwrap = true 71 } 72 if lb.Operator == "??" { 73 lwrap = true 74 } 75 if operator.IsBoolean(lb.Operator) && n.Operator != lb.Operator { 76 lwrap = true 77 } 78 } 79 if rb, ok := n.Right.(*BinaryNode); ok { 80 if operator.Less(rb.Operator, n.Operator) { 81 rwrap = true 82 } 83 if operator.IsBoolean(rb.Operator) && n.Operator != rb.Operator { 84 rwrap = true 85 } 86 } 87 88 if _, ok := n.Left.(*ConditionalNode); ok { 89 lwrap = true 90 } 91 if _, ok := n.Right.(*ConditionalNode); ok { 92 rwrap = true 93 } 94 95 if lwrap { 96 lhs = fmt.Sprintf("(%s)", n.Left.String()) 97 } else { 98 lhs = n.Left.String() 99 } 100 101 if rwrap { 102 rhs = fmt.Sprintf("(%s)", n.Right.String()) 103 } else { 104 rhs = n.Right.String() 105 } 106 107 return fmt.Sprintf("%s %s %s", lhs, n.Operator, rhs) 108 } 109 110 func (n *ChainNode) String() string { 111 return n.Node.String() 112 } 113 114 func (n *MemberNode) String() string { 115 node := n.Node.String() 116 if _, ok := n.Node.(*BinaryNode); ok { 117 node = fmt.Sprintf("(%s)", node) 118 } 119 120 if n.Optional { 121 if str, ok := n.Property.(*StringNode); ok && utils.IsValidIdentifier(str.Value) { 122 return fmt.Sprintf("%s?.%s", node, str.Value) 123 } else { 124 return fmt.Sprintf("%s?.[%s]", node, n.Property.String()) 125 } 126 } 127 if str, ok := n.Property.(*StringNode); ok && utils.IsValidIdentifier(str.Value) { 128 if _, ok := n.Node.(*PointerNode); ok { 129 return fmt.Sprintf(".%s", str.Value) 130 } 131 return fmt.Sprintf("%s.%s", node, str.Value) 132 } 133 return fmt.Sprintf("%s[%s]", node, n.Property.String()) 134 } 135 136 func (n *SliceNode) String() string { 137 if n.From == nil && n.To == nil { 138 return fmt.Sprintf("%s[:]", n.Node.String()) 139 } 140 if n.From == nil { 141 return fmt.Sprintf("%s[:%s]", n.Node.String(), n.To.String()) 142 } 143 if n.To == nil { 144 return fmt.Sprintf("%s[%s:]", n.Node.String(), n.From.String()) 145 } 146 return fmt.Sprintf("%s[%s:%s]", n.Node.String(), n.From.String(), n.To.String()) 147 } 148 149 func (n *CallNode) String() string { 150 arguments := make([]string, len(n.Arguments)) 151 for i, arg := range n.Arguments { 152 arguments[i] = arg.String() 153 } 154 return fmt.Sprintf("%s(%s)", n.Callee.String(), strings.Join(arguments, ", ")) 155 } 156 157 func (n *BuiltinNode) String() string { 158 arguments := make([]string, len(n.Arguments)) 159 for i, arg := range n.Arguments { 160 arguments[i] = arg.String() 161 } 162 return fmt.Sprintf("%s(%s)", n.Name, strings.Join(arguments, ", ")) 163 } 164 165 func (n *ClosureNode) String() string { 166 return n.Node.String() 167 } 168 169 func (n *PointerNode) String() string { 170 return fmt.Sprintf("#%s", n.Name) 171 } 172 173 func (n *VariableDeclaratorNode) String() string { 174 return fmt.Sprintf("let %s = %s; %s", n.Name, n.Value.String(), n.Expr.String()) 175 } 176 177 func (n *ConditionalNode) String() string { 178 var cond, exp1, exp2 string 179 if _, ok := n.Cond.(*ConditionalNode); ok { 180 cond = fmt.Sprintf("(%s)", n.Cond.String()) 181 } else { 182 cond = n.Cond.String() 183 } 184 if _, ok := n.Exp1.(*ConditionalNode); ok { 185 exp1 = fmt.Sprintf("(%s)", n.Exp1.String()) 186 } else { 187 exp1 = n.Exp1.String() 188 } 189 if _, ok := n.Exp2.(*ConditionalNode); ok { 190 exp2 = fmt.Sprintf("(%s)", n.Exp2.String()) 191 } else { 192 exp2 = n.Exp2.String() 193 } 194 return fmt.Sprintf("%s ? %s : %s", cond, exp1, exp2) 195 } 196 197 func (n *ArrayNode) String() string { 198 nodes := make([]string, len(n.Nodes)) 199 for i, node := range n.Nodes { 200 nodes[i] = node.String() 201 } 202 return fmt.Sprintf("[%s]", strings.Join(nodes, ", ")) 203 } 204 205 func (n *MapNode) String() string { 206 pairs := make([]string, len(n.Pairs)) 207 for i, pair := range n.Pairs { 208 pairs[i] = pair.String() 209 } 210 return fmt.Sprintf("{%s}", strings.Join(pairs, ", ")) 211 } 212 213 func (n *PairNode) String() string { 214 if str, ok := n.Key.(*StringNode); ok { 215 if utils.IsValidIdentifier(str.Value) { 216 return fmt.Sprintf("%s: %s", str.Value, n.Value.String()) 217 } 218 return fmt.Sprintf("%s: %s", str.String(), n.Value.String()) 219 } 220 return fmt.Sprintf("(%s): %s", n.Key.String(), n.Value.String()) 221 }