expr/builtin-base.go

219 lines
5.5 KiB
Go
Raw Normal View History

2024-04-20 06:52:33 +02:00
// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
// All rights reserved.
// builtin-base.go
2024-04-20 06:52:33 +02:00
package expr
import (
"fmt"
2024-04-20 07:29:42 +02:00
"math"
"strconv"
2024-04-20 06:52:33 +02:00
)
const (
ParamDenominator = "denominator"
)
func isNilFunc(ctx ExprContext, name string, args map[string]any) (result any, err error) {
result = args[ParamValue] == nil
2024-04-20 07:29:42 +02:00
return
}
func isIntFunc(ctx ExprContext, name string, args map[string]any) (result any, err error) {
result = IsInteger(args[ParamValue])
return
}
func isFloatFunc(ctx ExprContext, name string, args map[string]any) (result any, err error) {
result = IsFloat(args[ParamValue])
return
}
func isBoolFunc(ctx ExprContext, name string, args map[string]any) (result any, err error) {
result = IsBool(args[ParamValue])
return
}
func isStringFunc(ctx ExprContext, name string, args map[string]any) (result any, err error) {
result = IsString(args[ParamValue])
return
}
func isFractionFunc(ctx ExprContext, name string, args map[string]any) (result any, err error) {
result = IsFract(args[ParamValue])
return
}
func isRationalFunc(ctx ExprContext, name string, args map[string]any) (result any, err error) {
result = IsRational(args[ParamValue])
return
}
func isListFunc(ctx ExprContext, name string, args map[string]any) (result any, err error) {
result = IsList(args[ParamValue])
return
}
func isDictionaryFunc(ctx ExprContext, name string, args map[string]any) (result any, err error) {
result = IsDict(args[ParamValue])
return
}
func boolFunc(ctx ExprContext, name string, args map[string]any) (result any, err error) {
switch v := args[ParamValue].(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 map[string]any) (result any, err error) {
switch v := args[ParamValue].(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 map[string]any) (result any, err error) {
switch v := args[ParamValue].(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 stringFunc(ctx ExprContext, name string, args map[string]any) (result any, err error) {
switch v := args[ParamValue].(type) {
case int64:
result = strconv.FormatInt(v, 10)
case float64:
result = strconv.FormatFloat(v, 'g', -1, 64)
case bool:
if v {
result = "true"
} else {
result = "false"
}
case string:
result = v
case *FractionType:
result = v.ToString(0)
case Formatter:
result = v.ToString(0)
case fmt.Stringer:
result = v.String()
default:
err = ErrCantConvert(name, v, "string")
}
return
}
func fractFunc(ctx ExprContext, name string, args map[string]any) (result any, err error) {
switch v := args[ParamValue].(type) {
case int64:
var den int64 = 1
var ok bool
if den, ok = args[ParamDenominator].(int64); !ok {
err = ErrExpectedGot(name, "integer", args[ParamDenominator])
} else if den == 0 {
err = ErrFuncDivisionByZero(name)
2024-04-20 07:29:42 +02:00
}
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")
2024-04-20 06:52:33 +02:00
}
return
}
// func iteratorFunc(ctx ExprContext, name string, args []any) (result any, err error) {
// return
// }
2024-04-20 06:52:33 +02:00
func ImportBuiltinsFuncs(ctx ExprContext) {
anyParams := []ExprFuncParam{
2024-06-09 10:13:37 +02:00
NewFuncParam(ParamValue),
}
ctx.RegisterFunc("isNil", NewGolangFunctor2(isNilFunc), TypeBoolean, anyParams)
ctx.RegisterFunc("isInt", NewGolangFunctor2(isIntFunc), TypeBoolean, anyParams)
ctx.RegisterFunc("isFloat", NewGolangFunctor2(isFloatFunc), TypeBoolean, anyParams)
ctx.RegisterFunc("isBool", NewGolangFunctor2(isBoolFunc), TypeBoolean, anyParams)
ctx.RegisterFunc("isString", NewGolangFunctor2(isStringFunc), TypeBoolean, anyParams)
ctx.RegisterFunc("isFract", NewGolangFunctor2(isFractionFunc), TypeBoolean, anyParams)
ctx.RegisterFunc("isRational", NewGolangFunctor2(isRationalFunc), TypeBoolean, anyParams)
ctx.RegisterFunc("isList", NewGolangFunctor2(isListFunc), TypeBoolean, anyParams)
ctx.RegisterFunc("isDict", NewGolangFunctor2(isDictionaryFunc), TypeBoolean, anyParams)
ctx.RegisterFunc("bool", NewGolangFunctor2(boolFunc), TypeBoolean, anyParams)
ctx.RegisterFunc("int", NewGolangFunctor2(intFunc), TypeInt, anyParams)
ctx.RegisterFunc("dec", NewGolangFunctor2(decFunc), TypeFloat, anyParams)
ctx.RegisterFunc("string", NewGolangFunctor2(stringFunc), TypeString, anyParams)
ctx.RegisterFunc("fract", NewGolangFunctor2(fractFunc), TypeFraction, []ExprFuncParam{
2024-06-09 10:13:37 +02:00
NewFuncParam(ParamValue),
NewFuncParamFlagDef(ParamDenominator, PfDefault, int64(1)),
})
2024-04-20 06:52:33 +02:00
}
func init() {
RegisterBuiltinModule("base", ImportBuiltinsFuncs, "Base expression tools like isNil(), int(), etc.")
2024-04-20 06:52:33 +02:00
}