src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/eval/builtin_fn_pred.go (about)

     1  package eval
     2  
     3  import (
     4  	"src.elv.sh/pkg/eval/errs"
     5  	"src.elv.sh/pkg/eval/vals"
     6  )
     7  
     8  // Basic predicate commands.
     9  
    10  func init() {
    11  	addBuiltinFns(map[string]any{
    12  		"bool":    vals.Bool,
    13  		"not":     not,
    14  		"is":      is,
    15  		"eq":      eq,
    16  		"not-eq":  notEq,
    17  		"compare": compare,
    18  	})
    19  }
    20  
    21  func not(v any) bool {
    22  	return !vals.Bool(v)
    23  }
    24  
    25  func is(args ...any) bool {
    26  	for i := 0; i+1 < len(args); i++ {
    27  		if args[i] != args[i+1] {
    28  			return false
    29  		}
    30  	}
    31  	return true
    32  }
    33  
    34  func eq(args ...any) bool {
    35  	for i := 0; i+1 < len(args); i++ {
    36  		if !vals.Equal(args[i], args[i+1]) {
    37  			return false
    38  		}
    39  	}
    40  	return true
    41  }
    42  
    43  func notEq(a, b any) bool {
    44  	return !vals.Equal(a, b)
    45  }
    46  
    47  // ErrUncomparable is raised by the compare and order commands when inputs contain
    48  // uncomparable values.
    49  var ErrUncomparable = errs.BadValue{
    50  	What:  `inputs to "compare" or "order"`,
    51  	Valid: "comparable values", Actual: "uncomparable values"}
    52  
    53  type compareOptions struct {
    54  	Total bool
    55  }
    56  
    57  func (opts *compareOptions) SetDefaultOptions() {}
    58  
    59  func compare(opts compareOptions, a, b any) (int, error) {
    60  	var o vals.Ordering
    61  	if opts.Total {
    62  		o = vals.CmpTotal(a, b)
    63  	} else {
    64  		o = vals.Cmp(a, b)
    65  	}
    66  	switch o {
    67  	case vals.CmpLess:
    68  		return -1, nil
    69  	case vals.CmpEqual:
    70  		return 0, nil
    71  	case vals.CmpMore:
    72  		return 1, nil
    73  	default:
    74  		return 0, ErrUncomparable
    75  	}
    76  }