// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). // All rights reserved. // builtin-base.go package expr import ( "math" "strconv" ) func isNilFunc(ctx ExprContext, name string, args []any) (result any, err error) { result = args[0] == nil return } func isIntFunc(ctx ExprContext, name string, args []any) (result any, err error) { result = IsInteger(args[0]) return } func isFloatFunc(ctx ExprContext, name string, args []any) (result any, err error) { result = IsFloat(args[0]) return } func isBoolFunc(ctx ExprContext, name string, args []any) (result any, err error) { result = IsBool(args[0]) return } func isStringFunc(ctx ExprContext, name string, args []any) (result any, err error) { result = IsString(args[0]) return } func isFractionFunc(ctx ExprContext, name string, args []any) (result any, err error) { result = IsFract(args[0]) return } func isRationalFunc(ctx ExprContext, name string, args []any) (result any, err error) { result = IsRational(args[0]) return } func isListFunc(ctx ExprContext, name string, args []any) (result any, err error) { result = IsList(args[0]) return } func isDictionaryFunc(ctx ExprContext, name string, args []any) (result any, err error) { result = IsDict(args[0]) return } func boolFunc(ctx ExprContext, name string, args []any) (result any, err error) { switch v := args[0].(type) { case int64: result = (v != 0) case *FractionType: result = v.num != 0 case float64: result = v != 0.0 case bool: result = v case string: result = len(v) > 0 default: err = errCantConvert(name, v, "bool") } return } func intFunc(ctx ExprContext, name string, args []any) (result any, err error) { switch v := args[0].(type) { case int64: result = v case float64: result = int64(math.Trunc(v)) case bool: if v { result = int64(1) } else { result = int64(0) } case string: var i int if i, err = strconv.Atoi(v); err == nil { result = int64(i) } default: err = errCantConvert(name, v, "int") } return } func decFunc(ctx ExprContext, name string, args []any) (result any, err error) { switch v := args[0].(type) { case int64: result = float64(v) case float64: result = v case bool: if v { result = float64(1) } else { result = float64(0) } case string: var f float64 if f, err = strconv.ParseFloat(v, 64); err == nil { result = f } case *FractionType: result = v.toFloat() default: err = errCantConvert(name, v, "float") } return } func fractFunc(ctx ExprContext, name string, args []any) (result any, err error) { switch v := args[0].(type) { case int64: var den int64 = 1 if len(args) > 1 { var ok bool if den, ok = args[1].(int64); !ok { err = errExpectedGot(name, "integer", args[1]) } else if den == 0 { err = errFuncDivisionByZero(name) } } if err == nil { result = newFraction(v, den) } case float64: result, err = float64ToFraction(v) case bool: if v { result = newFraction(1, 1) } else { result = newFraction(0, 1) } case string: result, err = makeGeneratingFraction(v) case *FractionType: result = v default: err = errCantConvert(name, v, "float") } return } func iteratorFunc(ctx ExprContext, name string, args []any) (result any, err error) { return } func ImportBuiltinsFuncs(ctx ExprContext) { anyParams := []ExprFuncParam{ NewFuncParam(ParamValue), } ctx.RegisterFunc("isNil", NewGolangFunctor(isNilFunc), TypeBoolean, anyParams) ctx.RegisterFunc("isInt", NewGolangFunctor(isIntFunc), TypeBoolean, anyParams) ctx.RegisterFunc("isFloat", NewGolangFunctor(isFloatFunc), TypeBoolean, anyParams) ctx.RegisterFunc("isBool", NewGolangFunctor(isBoolFunc), TypeBoolean, anyParams) ctx.RegisterFunc("isString", NewGolangFunctor(isStringFunc), TypeBoolean, anyParams) ctx.RegisterFunc("isFract", NewGolangFunctor(isFractionFunc), TypeBoolean, anyParams) ctx.RegisterFunc("isRational", NewGolangFunctor(isRationalFunc), TypeBoolean, anyParams) ctx.RegisterFunc("isList", NewGolangFunctor(isListFunc), TypeBoolean, anyParams) ctx.RegisterFunc("isDict", NewGolangFunctor(isDictionaryFunc), TypeBoolean, anyParams) ctx.RegisterFunc("bool", NewGolangFunctor(boolFunc), TypeBoolean, anyParams) ctx.RegisterFunc("int", NewGolangFunctor(intFunc), TypeInt, anyParams) ctx.RegisterFunc("dec", NewGolangFunctor(decFunc), TypeFloat, anyParams) ctx.RegisterFunc("fract", NewGolangFunctor(fractFunc), TypeFraction, []ExprFuncParam{ NewFuncParam(ParamValue), NewFuncParamFlagDef("denominator", PfDefault, 1), }) } func init() { RegisterBuiltinModule("base", ImportBuiltinsFuncs, "Base expression tools like isNil(), int(), etc.") }