mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-05 03:17:50 +08:00
155 lines
2.2 KiB
Go
155 lines
2.2 KiB
Go
package eval
|
|
|
|
import (
|
|
"math"
|
|
"math/rand"
|
|
|
|
"github.com/elves/elvish/pkg/eval/vals"
|
|
)
|
|
|
|
// Numerical operations.
|
|
|
|
func init() {
|
|
addBuiltinFns(map[string]interface{}{
|
|
// Constructor
|
|
"float64": toFloat64,
|
|
|
|
// Comparison
|
|
"<": lt,
|
|
"<=": le,
|
|
"==": eqNum,
|
|
"!=": ne,
|
|
">": gt,
|
|
">=": ge,
|
|
|
|
// Arithmetics
|
|
"+": plus,
|
|
"-": minus,
|
|
"*": times,
|
|
"/": slash,
|
|
"^": math.Pow,
|
|
"%": mod,
|
|
|
|
// Random
|
|
"rand": rand.Float64,
|
|
"randint": randint,
|
|
})
|
|
}
|
|
|
|
func toFloat64(f float64) float64 {
|
|
return f
|
|
}
|
|
|
|
func lt(nums ...float64) bool {
|
|
for i := 0; i < len(nums)-1; i++ {
|
|
if !(nums[i] < nums[i+1]) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func le(nums ...float64) bool {
|
|
for i := 0; i < len(nums)-1; i++ {
|
|
if !(nums[i] <= nums[i+1]) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func eqNum(nums ...float64) bool {
|
|
for i := 0; i < len(nums)-1; i++ {
|
|
if !(nums[i] == nums[i+1]) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func ne(nums ...float64) bool {
|
|
for i := 0; i < len(nums)-1; i++ {
|
|
if !(nums[i] != nums[i+1]) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func gt(nums ...float64) bool {
|
|
for i := 0; i < len(nums)-1; i++ {
|
|
if !(nums[i] > nums[i+1]) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func ge(nums ...float64) bool {
|
|
for i := 0; i < len(nums)-1; i++ {
|
|
if !(nums[i] >= nums[i+1]) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func plus(nums ...float64) float64 {
|
|
sum := 0.0
|
|
for _, f := range nums {
|
|
sum += f
|
|
}
|
|
return sum
|
|
}
|
|
|
|
func minus(sum float64, nums ...float64) float64 {
|
|
if len(nums) == 0 {
|
|
// Unary -
|
|
return -sum
|
|
}
|
|
for _, f := range nums {
|
|
sum -= f
|
|
}
|
|
return sum
|
|
}
|
|
|
|
func times(nums ...float64) float64 {
|
|
prod := 1.0
|
|
for _, f := range nums {
|
|
prod *= f
|
|
}
|
|
return prod
|
|
}
|
|
|
|
func slash(fm *Frame, args ...float64) error {
|
|
if len(args) == 0 {
|
|
// cd /
|
|
return fm.Chdir("/")
|
|
}
|
|
// Division
|
|
divide(fm, args[0], args[1:]...)
|
|
return nil
|
|
}
|
|
|
|
func divide(fm *Frame, prod float64, nums ...float64) {
|
|
out := fm.ports[1].Chan
|
|
for _, f := range nums {
|
|
prod /= f
|
|
}
|
|
out <- vals.FromGo(prod)
|
|
}
|
|
|
|
func mod(a, b int) (int, error) {
|
|
if b == 0 {
|
|
return 0, ErrArgs
|
|
}
|
|
return a % b, nil
|
|
}
|
|
|
|
func randint(low, high int) (int, error) {
|
|
if low >= high {
|
|
return 0, ErrArgs
|
|
}
|
|
return low + rand.Intn(high-low), nil
|
|
}
|