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  }