github.com/NeowayLabs/nash@v0.2.2-0.20200127205349-a227041ffd50/ast/node_args.go (about)

     1  package ast
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/madlambda/nash/scanner"
     7  	"github.com/madlambda/nash/token"
     8  )
     9  
    10  // ArgFromToken is a helper to get an argument based on the lexer token
    11  func ExprFromToken(val scanner.Token) (Expr, error) {
    12  	switch val.Type() {
    13  	case token.Arg:
    14  		return NewStringExpr(token.NewFileInfo(val.Line(), val.Column()), val.Value(), false), nil
    15  	case token.String:
    16  		return NewStringExpr(token.NewFileInfo(val.Line(), val.Column()), val.Value(), true), nil
    17  	case token.Variable:
    18  		return NewVarExpr(token.NewFileInfo(val.Line(), val.Column()), val.Value()), nil
    19  	}
    20  
    21  	return nil, fmt.Errorf("argFromToken doesn't support type %v", val)
    22  }
    23  
    24  // NewArgString creates a new string argument
    25  func NewStringExpr(info token.FileInfo, value string, quoted bool) *StringExpr {
    26  	return &StringExpr{
    27  		NodeType: NodeStringExpr,
    28  		FileInfo: info,
    29  
    30  		str:    value,
    31  		quoted: quoted,
    32  	}
    33  }
    34  
    35  // Value returns the argument string value
    36  func (s *StringExpr) Value() string {
    37  	return s.str
    38  }
    39  
    40  func (s *StringExpr) SetValue(a string) {
    41  	s.str = a
    42  }
    43  
    44  func (s *StringExpr) IsEqual(other Node) bool {
    45  	if !s.equal(s, other) {
    46  		return false
    47  	}
    48  
    49  	value, ok := other.(*StringExpr)
    50  
    51  	if !ok {
    52  		return false
    53  	}
    54  
    55  	if s.quoted != value.quoted {
    56  		return false
    57  	}
    58  
    59  	return s.str == value.str
    60  }
    61  
    62  func NewIntExpr(info token.FileInfo, val int) *IntExpr {
    63  	return &IntExpr{
    64  		NodeType: NodeIntExpr,
    65  		FileInfo: info,
    66  
    67  		val: val,
    68  	}
    69  }
    70  
    71  func (i *IntExpr) Value() int { return i.val }
    72  
    73  func (i *IntExpr) IsEqual(other Node) bool {
    74  	if !i.equal(i, other) {
    75  		return false
    76  	}
    77  
    78  	o, ok := other.(*IntExpr)
    79  
    80  	if !ok {
    81  		return false
    82  	}
    83  
    84  	return i.val == o.val
    85  }
    86  
    87  func NewListExpr(info token.FileInfo, values []Expr) *ListExpr {
    88  	return NewListVariadicExpr(info, values, false)
    89  }
    90  
    91  func NewListVariadicExpr(info token.FileInfo, values []Expr, variadic bool) *ListExpr {
    92  	return &ListExpr{
    93  		NodeType: NodeListExpr,
    94  		FileInfo: info,
    95  
    96  		List:       values,
    97  		IsVariadic: variadic,
    98  	}
    99  }
   100  
   101  // PushExpr push an expression to end of the list
   102  func (l *ListExpr) PushExpr(a Expr) {
   103  	l.List = append(l.List, a)
   104  }
   105  
   106  func (l *ListExpr) IsEqual(other Node) bool {
   107  	if !l.equal(l, other) {
   108  		return false
   109  	}
   110  
   111  	o, ok := other.(*ListExpr)
   112  
   113  	if !ok {
   114  		return false
   115  	}
   116  
   117  	if len(l.List) != len(o.List) {
   118  		return false
   119  	}
   120  
   121  	for i, val := range l.List {
   122  		oval := o.List[i]
   123  		if !val.IsEqual(oval) {
   124  			debug("%v(%s) != %v(%s)", val, val.Type(),
   125  				oval, oval.Type())
   126  			return false
   127  		}
   128  	}
   129  
   130  	return true
   131  }
   132  
   133  func NewConcatExpr(info token.FileInfo, parts []Expr) *ConcatExpr {
   134  	return &ConcatExpr{
   135  		NodeType: NodeConcatExpr,
   136  		FileInfo: info,
   137  
   138  		concat: parts,
   139  	}
   140  }
   141  
   142  // PushExpr push an expression to end of the concat list
   143  func (c *ConcatExpr) PushExpr(a Expr) {
   144  	c.concat = append(c.concat, a)
   145  }
   146  
   147  // SetConcatList set the concatenation parts
   148  func (c *ConcatExpr) SetConcat(v []Expr) {
   149  	c.concat = v
   150  }
   151  
   152  func (c *ConcatExpr) List() []Expr { return c.concat }
   153  
   154  func (c *ConcatExpr) IsEqual(other Node) bool {
   155  	if !c.equal(c, other) {
   156  		return false
   157  	}
   158  
   159  	o, ok := other.(*ConcatExpr)
   160  
   161  	if !ok {
   162  		return false
   163  	}
   164  
   165  	if len(c.concat) != len(o.concat) {
   166  		return false
   167  	}
   168  
   169  	for i := 0; i < len(c.concat); i++ {
   170  		if !c.concat[i].IsEqual(o.concat[i]) {
   171  			return false
   172  		}
   173  	}
   174  
   175  	return true
   176  }
   177  
   178  func NewVarExpr(info token.FileInfo, name string) *VarExpr {
   179  	return NewVarVariadicExpr(info, name, false)
   180  }
   181  
   182  func NewVarVariadicExpr(info token.FileInfo, name string, isVariadic bool) *VarExpr {
   183  	return &VarExpr{
   184  		NodeType:   NodeVarExpr,
   185  		FileInfo:   info,
   186  		Name:       name,
   187  		IsVariadic: isVariadic,
   188  	}
   189  }
   190  
   191  func (v *VarExpr) IsEqual(other Node) bool {
   192  	if !v.equal(v, other) {
   193  		return false
   194  	}
   195  
   196  	o, ok := other.(*VarExpr)
   197  	if !ok {
   198  		return false
   199  	}
   200  
   201  	return v.Name == o.Name &&
   202  		v.IsVariadic == o.IsVariadic
   203  }
   204  
   205  func NewIndexExpr(info token.FileInfo, va *VarExpr, idx Expr) *IndexExpr {
   206  	return NewIndexVariadicExpr(info, va, idx, false)
   207  }
   208  
   209  func NewIndexVariadicExpr(info token.FileInfo, va *VarExpr, idx Expr, variadic bool) *IndexExpr {
   210  	return &IndexExpr{
   211  		NodeType: NodeIndexExpr,
   212  		FileInfo: info,
   213  
   214  		Var:        va,
   215  		Index:      idx,
   216  		IsVariadic: variadic,
   217  	}
   218  }
   219  
   220  func (i *IndexExpr) IsEqual(other Node) bool {
   221  	if !i.equal(i, other) {
   222  		return false
   223  	}
   224  
   225  	o, ok := other.(*IndexExpr)
   226  	if !ok {
   227  		return false
   228  	}
   229  
   230  	return i.Var.IsEqual(o.Var) &&
   231  		i.Index.IsEqual(o.Index) &&
   232  		i.IsVariadic == o.IsVariadic
   233  }