diff options
Diffstat (limited to 'vendor/github.com/d5/tengo/v2/builtins.go')
-rw-r--r-- | vendor/github.com/d5/tengo/v2/builtins.go | 502 |
1 files changed, 502 insertions, 0 deletions
diff --git a/vendor/github.com/d5/tengo/v2/builtins.go b/vendor/github.com/d5/tengo/v2/builtins.go new file mode 100644 index 00000000..87f7fc3d --- /dev/null +++ b/vendor/github.com/d5/tengo/v2/builtins.go @@ -0,0 +1,502 @@ +package tengo + +var builtinFuncs = []*BuiltinFunction{ + { + Name: "len", + Value: builtinLen, + }, + { + Name: "copy", + Value: builtinCopy, + }, + { + Name: "append", + Value: builtinAppend, + }, + { + Name: "string", + Value: builtinString, + }, + { + Name: "int", + Value: builtinInt, + }, + { + Name: "bool", + Value: builtinBool, + }, + { + Name: "float", + Value: builtinFloat, + }, + { + Name: "char", + Value: builtinChar, + }, + { + Name: "bytes", + Value: builtinBytes, + }, + { + Name: "time", + Value: builtinTime, + }, + { + Name: "is_int", + Value: builtinIsInt, + }, + { + Name: "is_float", + Value: builtinIsFloat, + }, + { + Name: "is_string", + Value: builtinIsString, + }, + { + Name: "is_bool", + Value: builtinIsBool, + }, + { + Name: "is_char", + Value: builtinIsChar, + }, + { + Name: "is_bytes", + Value: builtinIsBytes, + }, + { + Name: "is_array", + Value: builtinIsArray, + }, + { + Name: "is_immutable_array", + Value: builtinIsImmutableArray, + }, + { + Name: "is_map", + Value: builtinIsMap, + }, + { + Name: "is_immutable_map", + Value: builtinIsImmutableMap, + }, + { + Name: "is_iterable", + Value: builtinIsIterable, + }, + { + Name: "is_time", + Value: builtinIsTime, + }, + { + Name: "is_error", + Value: builtinIsError, + }, + { + Name: "is_undefined", + Value: builtinIsUndefined, + }, + { + Name: "is_function", + Value: builtinIsFunction, + }, + { + Name: "is_callable", + Value: builtinIsCallable, + }, + { + Name: "type_name", + Value: builtinTypeName, + }, + { + Name: "format", + Value: builtinFormat, + }, +} + +// GetAllBuiltinFunctions returns all builtin function objects. +func GetAllBuiltinFunctions() []*BuiltinFunction { + return append([]*BuiltinFunction{}, builtinFuncs...) +} + +func builtinTypeName(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + return &String{Value: args[0].TypeName()}, nil +} + +func builtinIsString(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + if _, ok := args[0].(*String); ok { + return TrueValue, nil + } + return FalseValue, nil +} + +func builtinIsInt(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + if _, ok := args[0].(*Int); ok { + return TrueValue, nil + } + return FalseValue, nil +} + +func builtinIsFloat(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + if _, ok := args[0].(*Float); ok { + return TrueValue, nil + } + return FalseValue, nil +} + +func builtinIsBool(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + if _, ok := args[0].(*Bool); ok { + return TrueValue, nil + } + return FalseValue, nil +} + +func builtinIsChar(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + if _, ok := args[0].(*Char); ok { + return TrueValue, nil + } + return FalseValue, nil +} + +func builtinIsBytes(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + if _, ok := args[0].(*Bytes); ok { + return TrueValue, nil + } + return FalseValue, nil +} + +func builtinIsArray(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + if _, ok := args[0].(*Array); ok { + return TrueValue, nil + } + return FalseValue, nil +} + +func builtinIsImmutableArray(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + if _, ok := args[0].(*ImmutableArray); ok { + return TrueValue, nil + } + return FalseValue, nil +} + +func builtinIsMap(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + if _, ok := args[0].(*Map); ok { + return TrueValue, nil + } + return FalseValue, nil +} + +func builtinIsImmutableMap(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + if _, ok := args[0].(*ImmutableMap); ok { + return TrueValue, nil + } + return FalseValue, nil +} + +func builtinIsTime(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + if _, ok := args[0].(*Time); ok { + return TrueValue, nil + } + return FalseValue, nil +} + +func builtinIsError(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + if _, ok := args[0].(*Error); ok { + return TrueValue, nil + } + return FalseValue, nil +} + +func builtinIsUndefined(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + if args[0] == UndefinedValue { + return TrueValue, nil + } + return FalseValue, nil +} + +func builtinIsFunction(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + switch args[0].(type) { + case *CompiledFunction: + return TrueValue, nil + } + return FalseValue, nil +} + +func builtinIsCallable(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + if args[0].CanCall() { + return TrueValue, nil + } + return FalseValue, nil +} + +func builtinIsIterable(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + if args[0].CanIterate() { + return TrueValue, nil + } + return FalseValue, nil +} + +// len(obj object) => int +func builtinLen(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + switch arg := args[0].(type) { + case *Array: + return &Int{Value: int64(len(arg.Value))}, nil + case *ImmutableArray: + return &Int{Value: int64(len(arg.Value))}, nil + case *String: + return &Int{Value: int64(len(arg.Value))}, nil + case *Bytes: + return &Int{Value: int64(len(arg.Value))}, nil + case *Map: + return &Int{Value: int64(len(arg.Value))}, nil + case *ImmutableMap: + return &Int{Value: int64(len(arg.Value))}, nil + default: + return nil, ErrInvalidArgumentType{ + Name: "first", + Expected: "array/string/bytes/map", + Found: arg.TypeName(), + } + } +} + +func builtinFormat(args ...Object) (Object, error) { + numArgs := len(args) + if numArgs == 0 { + return nil, ErrWrongNumArguments + } + format, ok := args[0].(*String) + if !ok { + return nil, ErrInvalidArgumentType{ + Name: "format", + Expected: "string", + Found: args[0].TypeName(), + } + } + if numArgs == 1 { + // okay to return 'format' directly as String is immutable + return format, nil + } + s, err := Format(format.Value, args[1:]...) + if err != nil { + return nil, err + } + return &String{Value: s}, nil +} + +func builtinCopy(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + return args[0].Copy(), nil +} + +func builtinString(args ...Object) (Object, error) { + argsLen := len(args) + if !(argsLen == 1 || argsLen == 2) { + return nil, ErrWrongNumArguments + } + if _, ok := args[0].(*String); ok { + return args[0], nil + } + v, ok := ToString(args[0]) + if ok { + if len(v) > MaxStringLen { + return nil, ErrStringLimit + } + return &String{Value: v}, nil + } + if argsLen == 2 { + return args[1], nil + } + return UndefinedValue, nil +} + +func builtinInt(args ...Object) (Object, error) { + argsLen := len(args) + if !(argsLen == 1 || argsLen == 2) { + return nil, ErrWrongNumArguments + } + if _, ok := args[0].(*Int); ok { + return args[0], nil + } + v, ok := ToInt64(args[0]) + if ok { + return &Int{Value: v}, nil + } + if argsLen == 2 { + return args[1], nil + } + return UndefinedValue, nil +} + +func builtinFloat(args ...Object) (Object, error) { + argsLen := len(args) + if !(argsLen == 1 || argsLen == 2) { + return nil, ErrWrongNumArguments + } + if _, ok := args[0].(*Float); ok { + return args[0], nil + } + v, ok := ToFloat64(args[0]) + if ok { + return &Float{Value: v}, nil + } + if argsLen == 2 { + return args[1], nil + } + return UndefinedValue, nil +} + +func builtinBool(args ...Object) (Object, error) { + if len(args) != 1 { + return nil, ErrWrongNumArguments + } + if _, ok := args[0].(*Bool); ok { + return args[0], nil + } + v, ok := ToBool(args[0]) + if ok { + if v { + return TrueValue, nil + } + return FalseValue, nil + } + return UndefinedValue, nil +} + +func builtinChar(args ...Object) (Object, error) { + argsLen := len(args) + if !(argsLen == 1 || argsLen == 2) { + return nil, ErrWrongNumArguments + } + if _, ok := args[0].(*Char); ok { + return args[0], nil + } + v, ok := ToRune(args[0]) + if ok { + return &Char{Value: v}, nil + } + if argsLen == 2 { + return args[1], nil + } + return UndefinedValue, nil +} + +func builtinBytes(args ...Object) (Object, error) { + argsLen := len(args) + if !(argsLen == 1 || argsLen == 2) { + return nil, ErrWrongNumArguments + } + + // bytes(N) => create a new bytes with given size N + if n, ok := args[0].(*Int); ok { + if n.Value > int64(MaxBytesLen) { + return nil, ErrBytesLimit + } + return &Bytes{Value: make([]byte, int(n.Value))}, nil + } + v, ok := ToByteSlice(args[0]) + if ok { + if len(v) > MaxBytesLen { + return nil, ErrBytesLimit + } + return &Bytes{Value: v}, nil + } + if argsLen == 2 { + return args[1], nil + } + return UndefinedValue, nil +} + +func builtinTime(args ...Object) (Object, error) { + argsLen := len(args) + if !(argsLen == 1 || argsLen == 2) { + return nil, ErrWrongNumArguments + } + if _, ok := args[0].(*Time); ok { + return args[0], nil + } + v, ok := ToTime(args[0]) + if ok { + return &Time{Value: v}, nil + } + if argsLen == 2 { + return args[1], nil + } + return UndefinedValue, nil +} + +// append(arr, items...) +func builtinAppend(args ...Object) (Object, error) { + if len(args) < 2 { + return nil, ErrWrongNumArguments + } + switch arg := args[0].(type) { + case *Array: + return &Array{Value: append(arg.Value, args[1:]...)}, nil + case *ImmutableArray: + return &Array{Value: append(arg.Value, args[1:]...)}, nil + default: + return nil, ErrInvalidArgumentType{ + Name: "first", + Expected: "array", + Found: arg.TypeName(), + } + } +} |