package xsql import ( "fmt" "math" "math/rand" ) func mathCall(name string, args []interface{}) (interface{}, bool) { switch name { case "abs": if v, ok := args[0].(int); ok { t := float64(v) var ret = int(math.Abs(t)) return ret, true } else if v, ok := args[0].(float64); ok { return math.Abs(v), true } else { return fmt.Errorf("only float64 & int type are supported"), false } case "acos": if v, e := toF64(args[0]); e == nil { return math.Acos(v), true } else { return e, false } case "asin": if v, e := toF64(args[0]); e == nil { return math.Asin(v), true } else { return e, false } case "atan": if v, e := toF64(args[0]); e == nil { return math.Atan(v), true } else { return e, false } case "atan2": if v1, e := toF64(args[0]); e == nil { if v2, e1 := toF64(args[1]); e1 == nil { return math.Atan2(v1, v2), true } else { return e1, false } } else { return e, false } case "bitand": v1, ok1 := args[0].(int) v2, ok2 := args[1].(int) if ok1 && ok2 { return v1 & v2, true } else { return fmt.Errorf("Expect int type for both operands."), false } case "bitor": v1, ok1 := args[0].(int) v2, ok2 := args[1].(int) if ok1 && ok2 { return v1 | v2, true } else { return fmt.Errorf("Expect int type for both operands."), false } case "bitxor": v1, ok1 := args[0].(int) v2, ok2 := args[1].(int) if ok1 && ok2 { return v1 ^ v2, true } else { return fmt.Errorf("Expect int type for both operands."), false } case "bitnot": v1, ok1 := args[0].(int) if ok1 { return ^v1, true } else { return fmt.Errorf("Expect int type for operand."), false } case "ceil": if v, e := toF64(args[0]); e == nil { return math.Ceil(v), true } else { return e, false } case "cos": if v, e := toF64(args[0]); e == nil { return math.Cos(v), true } else { return e, false } case "cosh": if v, e := toF64(args[0]); e == nil { return math.Cosh(v), true } else { return e, false } case "exp": if v, e := toF64(args[0]); e == nil { return math.Exp(v), true } else { return e, false } case "ln": if v, e := toF64(args[0]); e == nil { return math.Log2(v), true } else { return e, false } case "log": if v, e := toF64(args[0]); e == nil { return math.Log10(v), true } else { return e, false } case "mod": if v, e := toF64(args[0]); e == nil { if v1, e1 := toF64(args[1]); e == nil { return math.Mod(v, v1), true } else { return e1, false } } else { return e, false } case "power": if v1, e := toF64(args[0]); e == nil { if v2, e2 := toF64(args[1]); e2 == nil { return math.Pow(v1, v2), true } else { return e2, false } } else { return e, false } case "rand": return rand.Float64(), true case "round": if v, e := toF64(args[0]); e == nil { return math.Round(v), true } else { return e, false } case "sign": if v, e := toF64(args[0]); e == nil { if v > 0 { return 1, true } else if v < 0 { return -1, true } else { return 0, true } } else { return e, false } case "sin": if v, e := toF64(args[0]); e == nil { return math.Sin(v), true } else { return e, false } case "sinh": if v, e := toF64(args[0]); e == nil { return math.Sinh(v), true } else { return e, false } case "sqrt": if v, e := toF64(args[0]); e == nil { return math.Sqrt(v), true } else { return e, false } case "tan": if v, e := toF64(args[0]); e == nil { return math.Tan(v), true } else { return e, false } case "tanh": if v, e := toF64(args[0]); e == nil { return math.Tanh(v), true } else { return e, false } } return fmt.Errorf("Unknown math function name."), false } func toF64(arg interface{}) (float64, error) { if v, ok := arg.(float64); ok { return v, nil } else if v, ok := arg.(int); ok { return float64(v), nil } return 0, fmt.Errorf("only float64 & int type are supported") }