mirror of
				https://github.com/chaisql/chai.git
				synced 2025-10-31 10:56:22 +08:00 
			
		
		
		
	 1659ae24e5
			
		
	
	1659ae24e5
	
	
	
		
			
			* Add math.acos and math.abs * Add acosh, asin, asinh, atan and atan2 * Test for proper function documentation * Cast to double on math functions * Use the new types.Value interface
		
			
				
	
	
		
			167 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			167 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package functions
 | |
| 
 | |
| import (
 | |
| 	"math"
 | |
| 
 | |
| 	"github.com/genjidb/genji/document"
 | |
| 	"github.com/genjidb/genji/internal/stringutil"
 | |
| 	"github.com/genjidb/genji/types"
 | |
| )
 | |
| 
 | |
| // MathFunctions returns all math package functions.
 | |
| func MathFunctions() Definitions {
 | |
| 	return mathFunctions
 | |
| }
 | |
| 
 | |
| var mathFunctions = Definitions{
 | |
| 	"floor": floor,
 | |
| 	"abs":   abs,
 | |
| 	"acos":  acos,
 | |
| 	"acosh": acosh,
 | |
| 	"asin":  asin,
 | |
| 	"asinh": asinh,
 | |
| 	"atan":  atan,
 | |
| 	"atan2": atan2,
 | |
| }
 | |
| 
 | |
| var floor = &ScalarDefinition{
 | |
| 	name:  "floor",
 | |
| 	arity: 1,
 | |
| 	callFn: func(args ...types.Value) (types.Value, error) {
 | |
| 		switch args[0].Type() {
 | |
| 		case types.DoubleValue:
 | |
| 			return types.NewDoubleValue(math.Floor(args[0].V().(float64))), nil
 | |
| 		case types.IntegerValue:
 | |
| 			return args[0], nil
 | |
| 		default:
 | |
| 			return nil, stringutil.Errorf("floor(arg1) expects arg1 to be a number")
 | |
| 		}
 | |
| 	},
 | |
| }
 | |
| 
 | |
| var abs = &ScalarDefinition{
 | |
| 	name:  "abs",
 | |
| 	arity: 1,
 | |
| 	callFn: func(args ...types.Value) (types.Value, error) {
 | |
| 		if args[0].Type() == types.NullValue {
 | |
| 			return types.NewNullValue(), nil
 | |
| 		}
 | |
| 		v, err := document.CastAs(args[0], types.DoubleValue)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		res := math.Abs(v.V().(float64))
 | |
| 		if args[0].Type() == types.IntegerValue {
 | |
| 			return document.CastAs(types.NewDoubleValue(res), types.IntegerValue)
 | |
| 		}
 | |
| 		return types.NewDoubleValue(res), nil
 | |
| 	},
 | |
| }
 | |
| 
 | |
| var acos = &ScalarDefinition{
 | |
| 	name:  "acos",
 | |
| 	arity: 1,
 | |
| 	callFn: func(args ...types.Value) (types.Value, error) {
 | |
| 		if args[0].Type() == types.NullValue {
 | |
| 			return types.NewNullValue(), nil
 | |
| 		}
 | |
| 		v, err := document.CastAs(args[0], types.DoubleValue)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		vv := v.V().(float64)
 | |
| 		if vv > 1.0 || vv < -1.0 {
 | |
| 			return nil, stringutil.Errorf("out of range, acos(arg1) expects arg1 to be within [-1, 1]")
 | |
| 		}
 | |
| 		res := math.Acos(vv)
 | |
| 		return types.NewDoubleValue(res), nil
 | |
| 	},
 | |
| }
 | |
| 
 | |
| var acosh = &ScalarDefinition{
 | |
| 	name:  "acosh",
 | |
| 	arity: 1,
 | |
| 	callFn: func(args ...types.Value) (types.Value, error) {
 | |
| 		if args[0].Type() == types.NullValue {
 | |
| 			return types.NewNullValue(), nil
 | |
| 		}
 | |
| 		v, err := document.CastAs(args[0], types.DoubleValue)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		vv := v.V().(float64)
 | |
| 		if vv < 1.0 {
 | |
| 			return nil, stringutil.Errorf("out of range, acosh(arg1) expects arg1 >= 1")
 | |
| 		}
 | |
| 		res := math.Acosh(vv)
 | |
| 		return types.NewDoubleValue(res), nil
 | |
| 	},
 | |
| }
 | |
| 
 | |
| var asin = &ScalarDefinition{
 | |
| 	name:  "asin",
 | |
| 	arity: 1,
 | |
| 	callFn: func(args ...types.Value) (types.Value, error) {
 | |
| 		if args[0].Type() == types.NullValue {
 | |
| 			return types.NewNullValue(), nil
 | |
| 		}
 | |
| 		v, err := document.CastAs(args[0], types.DoubleValue)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		vv := v.V().(float64)
 | |
| 		if vv > 1.0 || vv < -1.0 {
 | |
| 			return nil, stringutil.Errorf("out of range, asin(arg1) expects arg1 to be within [-1, 1]")
 | |
| 		}
 | |
| 		res := math.Asin(vv)
 | |
| 		return types.NewDoubleValue(res), nil
 | |
| 	},
 | |
| }
 | |
| 
 | |
| var asinh = &ScalarDefinition{
 | |
| 	name:  "asinh",
 | |
| 	arity: 1,
 | |
| 	callFn: func(args ...types.Value) (types.Value, error) {
 | |
| 		v, err := document.CastAs(args[0], types.DoubleValue)
 | |
| 		if err != nil || v.Type() == types.NullValue {
 | |
| 			return v, err
 | |
| 		}
 | |
| 		vv := v.V().(float64)
 | |
| 		res := math.Asinh(vv)
 | |
| 		return types.NewDoubleValue(res), nil
 | |
| 	},
 | |
| }
 | |
| 
 | |
| var atan = &ScalarDefinition{
 | |
| 	name:  "atan",
 | |
| 	arity: 1,
 | |
| 	callFn: func(args ...types.Value) (types.Value, error) {
 | |
| 		v, err := document.CastAs(args[0], types.DoubleValue)
 | |
| 		if err != nil || v.Type() == types.NullValue {
 | |
| 			return v, err
 | |
| 		}
 | |
| 		vv := v.V().(float64)
 | |
| 		res := math.Atan(vv)
 | |
| 		return types.NewDoubleValue(res), nil
 | |
| 	},
 | |
| }
 | |
| 
 | |
| var atan2 = &ScalarDefinition{
 | |
| 	name:  "atan2",
 | |
| 	arity: 2,
 | |
| 	callFn: func(args ...types.Value) (types.Value, error) {
 | |
| 		vA, err := document.CastAs(args[0], types.DoubleValue)
 | |
| 		if err != nil || vA.Type() == types.NullValue {
 | |
| 			return vA, err
 | |
| 		}
 | |
| 		vvA := vA.V().(float64)
 | |
| 		vB, err := document.CastAs(args[1], types.DoubleValue)
 | |
| 		if err != nil || vB.Type() == types.NullValue {
 | |
| 			return vB, err
 | |
| 		}
 | |
| 		vvB := vB.V().(float64)
 | |
| 		res := math.Atan2(vvA, vvB)
 | |
| 		return types.NewDoubleValue(res), nil
 | |
| 	},
 | |
| }
 |