mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-10-12 18:51:02 +08:00
254 lines
5.8 KiB
Go
254 lines
5.8 KiB
Go
package ast
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/expr-lang/expr/parser/operator"
|
|
"github.com/expr-lang/expr/parser/utils"
|
|
)
|
|
|
|
func (n *NilNode) String() string {
|
|
return "nil"
|
|
}
|
|
|
|
func (n *IdentifierNode) String() string {
|
|
return n.Value
|
|
}
|
|
|
|
func (n *IntegerNode) String() string {
|
|
return fmt.Sprintf("%d", n.Value)
|
|
}
|
|
|
|
func (n *FloatNode) String() string {
|
|
return fmt.Sprintf("%v", n.Value)
|
|
}
|
|
|
|
func (n *BoolNode) String() string {
|
|
return fmt.Sprintf("%t", n.Value)
|
|
}
|
|
|
|
func (n *StringNode) String() string {
|
|
return fmt.Sprintf("%q", n.Value)
|
|
}
|
|
|
|
func (n *ConstantNode) String() string {
|
|
if n.Value == nil {
|
|
return "nil"
|
|
}
|
|
b, err := json.Marshal(n.Value)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return string(b)
|
|
}
|
|
|
|
func (n *UnaryNode) String() string {
|
|
op := n.Operator
|
|
if n.Operator == "not" {
|
|
op = fmt.Sprintf("%s ", n.Operator)
|
|
}
|
|
wrap := false
|
|
switch b := n.Node.(type) {
|
|
case *BinaryNode:
|
|
if operator.Binary[b.Operator].Precedence <
|
|
operator.Unary[n.Operator].Precedence {
|
|
wrap = true
|
|
}
|
|
case *ConditionalNode:
|
|
wrap = true
|
|
}
|
|
if wrap {
|
|
return fmt.Sprintf("%s(%s)", op, n.Node.String())
|
|
}
|
|
return fmt.Sprintf("%s%s", op, n.Node.String())
|
|
}
|
|
|
|
func (n *BinaryNode) String() string {
|
|
if n.Operator == ".." {
|
|
return fmt.Sprintf("%s..%s", n.Left, n.Right)
|
|
}
|
|
|
|
var lhs, rhs string
|
|
var lwrap, rwrap bool
|
|
|
|
if l, ok := n.Left.(*UnaryNode); ok {
|
|
if operator.Unary[l.Operator].Precedence <
|
|
operator.Binary[n.Operator].Precedence {
|
|
lwrap = true
|
|
}
|
|
}
|
|
if lb, ok := n.Left.(*BinaryNode); ok {
|
|
if operator.Less(lb.Operator, n.Operator) {
|
|
lwrap = true
|
|
}
|
|
if operator.Binary[lb.Operator].Precedence ==
|
|
operator.Binary[n.Operator].Precedence &&
|
|
operator.Binary[n.Operator].Associativity == operator.Right {
|
|
lwrap = true
|
|
}
|
|
if lb.Operator == "??" {
|
|
lwrap = true
|
|
}
|
|
if operator.IsBoolean(lb.Operator) && n.Operator != lb.Operator {
|
|
lwrap = true
|
|
}
|
|
}
|
|
if rb, ok := n.Right.(*BinaryNode); ok {
|
|
if operator.Less(rb.Operator, n.Operator) {
|
|
rwrap = true
|
|
}
|
|
if operator.Binary[rb.Operator].Precedence ==
|
|
operator.Binary[n.Operator].Precedence &&
|
|
operator.Binary[n.Operator].Associativity == operator.Left {
|
|
rwrap = true
|
|
}
|
|
if operator.IsBoolean(rb.Operator) && n.Operator != rb.Operator {
|
|
rwrap = true
|
|
}
|
|
}
|
|
|
|
if _, ok := n.Left.(*ConditionalNode); ok {
|
|
lwrap = true
|
|
}
|
|
if _, ok := n.Right.(*ConditionalNode); ok {
|
|
rwrap = true
|
|
}
|
|
|
|
if lwrap {
|
|
lhs = fmt.Sprintf("(%s)", n.Left.String())
|
|
} else {
|
|
lhs = n.Left.String()
|
|
}
|
|
|
|
if rwrap {
|
|
rhs = fmt.Sprintf("(%s)", n.Right.String())
|
|
} else {
|
|
rhs = n.Right.String()
|
|
}
|
|
|
|
return fmt.Sprintf("%s %s %s", lhs, n.Operator, rhs)
|
|
}
|
|
|
|
func (n *ChainNode) String() string {
|
|
return n.Node.String()
|
|
}
|
|
|
|
func (n *MemberNode) String() string {
|
|
node := n.Node.String()
|
|
if _, ok := n.Node.(*BinaryNode); ok {
|
|
node = fmt.Sprintf("(%s)", node)
|
|
}
|
|
|
|
if n.Optional {
|
|
if str, ok := n.Property.(*StringNode); ok && utils.IsValidIdentifier(str.Value) {
|
|
return fmt.Sprintf("%s?.%s", node, str.Value)
|
|
} else {
|
|
return fmt.Sprintf("%s?.[%s]", node, n.Property.String())
|
|
}
|
|
}
|
|
if str, ok := n.Property.(*StringNode); ok && utils.IsValidIdentifier(str.Value) {
|
|
if _, ok := n.Node.(*PointerNode); ok {
|
|
return fmt.Sprintf(".%s", str.Value)
|
|
}
|
|
return fmt.Sprintf("%s.%s", node, str.Value)
|
|
}
|
|
return fmt.Sprintf("%s[%s]", node, n.Property.String())
|
|
}
|
|
|
|
func (n *SliceNode) String() string {
|
|
if n.From == nil && n.To == nil {
|
|
return fmt.Sprintf("%s[:]", n.Node.String())
|
|
}
|
|
if n.From == nil {
|
|
return fmt.Sprintf("%s[:%s]", n.Node.String(), n.To.String())
|
|
}
|
|
if n.To == nil {
|
|
return fmt.Sprintf("%s[%s:]", n.Node.String(), n.From.String())
|
|
}
|
|
return fmt.Sprintf("%s[%s:%s]", n.Node.String(), n.From.String(), n.To.String())
|
|
}
|
|
|
|
func (n *CallNode) String() string {
|
|
arguments := make([]string, len(n.Arguments))
|
|
for i, arg := range n.Arguments {
|
|
arguments[i] = arg.String()
|
|
}
|
|
return fmt.Sprintf("%s(%s)", n.Callee.String(), strings.Join(arguments, ", "))
|
|
}
|
|
|
|
func (n *BuiltinNode) String() string {
|
|
arguments := make([]string, len(n.Arguments))
|
|
for i, arg := range n.Arguments {
|
|
arguments[i] = arg.String()
|
|
}
|
|
return fmt.Sprintf("%s(%s)", n.Name, strings.Join(arguments, ", "))
|
|
}
|
|
|
|
func (n *PredicateNode) String() string {
|
|
return n.Node.String()
|
|
}
|
|
|
|
func (n *PointerNode) String() string {
|
|
return fmt.Sprintf("#%s", n.Name)
|
|
}
|
|
|
|
func (n *VariableDeclaratorNode) String() string {
|
|
return fmt.Sprintf("let %s = %s; %s", n.Name, n.Value.String(), n.Expr.String())
|
|
}
|
|
|
|
func (n *SequenceNode) String() string {
|
|
nodes := make([]string, len(n.Nodes))
|
|
for i, node := range n.Nodes {
|
|
nodes[i] = node.String()
|
|
}
|
|
return strings.Join(nodes, "; ")
|
|
}
|
|
|
|
func (n *ConditionalNode) String() string {
|
|
var cond, exp1, exp2 string
|
|
if _, ok := n.Cond.(*ConditionalNode); ok {
|
|
cond = fmt.Sprintf("(%s)", n.Cond.String())
|
|
} else {
|
|
cond = n.Cond.String()
|
|
}
|
|
if _, ok := n.Exp1.(*ConditionalNode); ok {
|
|
exp1 = fmt.Sprintf("(%s)", n.Exp1.String())
|
|
} else {
|
|
exp1 = n.Exp1.String()
|
|
}
|
|
if _, ok := n.Exp2.(*ConditionalNode); ok {
|
|
exp2 = fmt.Sprintf("(%s)", n.Exp2.String())
|
|
} else {
|
|
exp2 = n.Exp2.String()
|
|
}
|
|
return fmt.Sprintf("%s ? %s : %s", cond, exp1, exp2)
|
|
}
|
|
|
|
func (n *ArrayNode) String() string {
|
|
nodes := make([]string, len(n.Nodes))
|
|
for i, node := range n.Nodes {
|
|
nodes[i] = node.String()
|
|
}
|
|
return fmt.Sprintf("[%s]", strings.Join(nodes, ", "))
|
|
}
|
|
|
|
func (n *MapNode) String() string {
|
|
pairs := make([]string, len(n.Pairs))
|
|
for i, pair := range n.Pairs {
|
|
pairs[i] = pair.String()
|
|
}
|
|
return fmt.Sprintf("{%s}", strings.Join(pairs, ", "))
|
|
}
|
|
|
|
func (n *PairNode) String() string {
|
|
if str, ok := n.Key.(*StringNode); ok {
|
|
if utils.IsValidIdentifier(str.Value) {
|
|
return fmt.Sprintf("%s: %s", str.Value, n.Value.String())
|
|
}
|
|
return fmt.Sprintf("%s: %s", str.String(), n.Value.String())
|
|
}
|
|
return fmt.Sprintf("(%s): %s", n.Key.String(), n.Value.String())
|
|
}
|