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 }