github.com/elves/Elvish@v0.12.0/eval/builtin_fn_num.go (about)

     1  package eval
     2  
     3  import (
     4  	"math"
     5  	"math/rand"
     6  
     7  	"github.com/elves/elvish/eval/vals"
     8  )
     9  
    10  // Numerical operations.
    11  
    12  func init() {
    13  	addBuiltinFns(map[string]interface{}{
    14  		// Comparison
    15  		"<":  lt,
    16  		"<=": le,
    17  		"==": eqNum,
    18  		"!=": ne,
    19  		">":  gt,
    20  		">=": ge,
    21  
    22  		// Arithmetics
    23  		"+": plus,
    24  		"-": minus,
    25  		"*": times,
    26  		"/": slash,
    27  		"^": math.Pow,
    28  		"%": func(a, b int) int { return a % b },
    29  
    30  		// Random
    31  		"rand":    rand.Float64,
    32  		"randint": randint,
    33  	})
    34  }
    35  
    36  func lt(nums ...float64) bool {
    37  	for i := 0; i < len(nums)-1; i++ {
    38  		if !(nums[i] < nums[i+1]) {
    39  			return false
    40  		}
    41  	}
    42  	return true
    43  }
    44  
    45  func le(nums ...float64) bool {
    46  	for i := 0; i < len(nums)-1; i++ {
    47  		if !(nums[i] <= nums[i+1]) {
    48  			return false
    49  		}
    50  	}
    51  	return true
    52  }
    53  
    54  func eqNum(nums ...float64) bool {
    55  	for i := 0; i < len(nums)-1; i++ {
    56  		if !(nums[i] == nums[i+1]) {
    57  			return false
    58  		}
    59  	}
    60  	return true
    61  }
    62  
    63  func ne(nums ...float64) bool {
    64  	for i := 0; i < len(nums)-1; i++ {
    65  		if !(nums[i] != nums[i+1]) {
    66  			return false
    67  		}
    68  	}
    69  	return true
    70  }
    71  
    72  func gt(nums ...float64) bool {
    73  	for i := 0; i < len(nums)-1; i++ {
    74  		if !(nums[i] > nums[i+1]) {
    75  			return false
    76  		}
    77  	}
    78  	return true
    79  }
    80  
    81  func ge(nums ...float64) bool {
    82  	for i := 0; i < len(nums)-1; i++ {
    83  		if !(nums[i] >= nums[i+1]) {
    84  			return false
    85  		}
    86  	}
    87  	return true
    88  }
    89  
    90  func plus(nums ...float64) float64 {
    91  	sum := 0.0
    92  	for _, f := range nums {
    93  		sum += f
    94  	}
    95  	return sum
    96  }
    97  
    98  func minus(sum float64, nums ...float64) float64 {
    99  	if len(nums) == 0 {
   100  		// Unary -
   101  		return -sum
   102  	}
   103  	for _, f := range nums {
   104  		sum -= f
   105  	}
   106  	return sum
   107  }
   108  
   109  func times(nums ...float64) float64 {
   110  	prod := 1.0
   111  	for _, f := range nums {
   112  		prod *= f
   113  	}
   114  	return prod
   115  }
   116  
   117  func slash(fm *Frame, args ...float64) error {
   118  	if len(args) == 0 {
   119  		// cd /
   120  		return fm.Chdir("/")
   121  	}
   122  	// Division
   123  	divide(fm, args[0], args[1:]...)
   124  	return nil
   125  }
   126  
   127  func divide(fm *Frame, prod float64, nums ...float64) {
   128  	out := fm.ports[1].Chan
   129  	for _, f := range nums {
   130  		prod /= f
   131  	}
   132  	out <- vals.FromGo(prod)
   133  }
   134  
   135  func randint(low, high int) (int, error) {
   136  	if low >= high {
   137  		return 0, ErrArgs
   138  	}
   139  	return low + rand.Intn(high-low), nil
   140  }