mirror of
https://github.com/cwinfo/matterbridge.git
synced 2025-06-27 19:19:24 +00:00
Add scripting (tengo) support for every incoming message (#731)
TengoModifyMessage allows you to specify the location of a tengo (https://github.com/d5/tengo/) script. This script will receive every incoming message and can be used to modify the Username and the Text of that message. The script will have the following global variables: to modify: msgUsername and msgText to read: msgChannel and msgAccount The script is reloaded on every message, so you can modify the script on the fly. Example script can be found in https://github.com/42wim/matterbridge/tree/master/gateway/bench.tengo and https://github.com/42wim/matterbridge/tree/master/contrib/example.tengo The example below will check if the text contains blah and if so, it'll replace the text and the username of that message. text := import("text") if text.re_match("blah",msgText) { msgText="replaced by this" msgUsername="fakeuser" } More information about tengo on: https://github.com/d5/tengo/blob/master/docs/tutorial.md and https://github.com/d5/tengo/blob/master/docs/stdlib.md
This commit is contained in:
130
vendor/github.com/d5/tengo/objects/array.go
generated
vendored
Normal file
130
vendor/github.com/d5/tengo/objects/array.go
generated
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// Array represents an array of objects.
|
||||
type Array struct {
|
||||
Value []Object
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *Array) TypeName() string {
|
||||
return "array"
|
||||
}
|
||||
|
||||
func (o *Array) String() string {
|
||||
var elements []string
|
||||
for _, e := range o.Value {
|
||||
elements = append(elements, e.String())
|
||||
}
|
||||
|
||||
return fmt.Sprintf("[%s]", strings.Join(elements, ", "))
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *Array) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
if rhs, ok := rhs.(*Array); ok {
|
||||
switch op {
|
||||
case token.Add:
|
||||
if len(rhs.Value) == 0 {
|
||||
return o, nil
|
||||
}
|
||||
return &Array{Value: append(o.Value, rhs.Value...)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *Array) Copy() Object {
|
||||
var c []Object
|
||||
for _, elem := range o.Value {
|
||||
c = append(c, elem.Copy())
|
||||
}
|
||||
|
||||
return &Array{Value: c}
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *Array) IsFalsy() bool {
|
||||
return len(o.Value) == 0
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *Array) Equals(x Object) bool {
|
||||
var xVal []Object
|
||||
switch x := x.(type) {
|
||||
case *Array:
|
||||
xVal = x.Value
|
||||
case *ImmutableArray:
|
||||
xVal = x.Value
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
if len(o.Value) != len(xVal) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i, e := range o.Value {
|
||||
if !e.Equals(xVal[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// IndexGet returns an element at a given index.
|
||||
func (o *Array) IndexGet(index Object) (res Object, err error) {
|
||||
intIdx, ok := index.(*Int)
|
||||
if !ok {
|
||||
err = ErrInvalidIndexType
|
||||
return
|
||||
}
|
||||
|
||||
idxVal := int(intIdx.Value)
|
||||
|
||||
if idxVal < 0 || idxVal >= len(o.Value) {
|
||||
res = UndefinedValue
|
||||
return
|
||||
}
|
||||
|
||||
res = o.Value[idxVal]
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// IndexSet sets an element at a given index.
|
||||
func (o *Array) IndexSet(index, value Object) (err error) {
|
||||
intIdx, ok := ToInt(index)
|
||||
if !ok {
|
||||
err = ErrInvalidIndexType
|
||||
return
|
||||
}
|
||||
|
||||
if intIdx < 0 || intIdx >= len(o.Value) {
|
||||
err = ErrIndexOutOfBounds
|
||||
return
|
||||
}
|
||||
|
||||
o.Value[intIdx] = value
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Iterate creates an array iterator.
|
||||
func (o *Array) Iterate() Iterator {
|
||||
return &ArrayIterator{
|
||||
v: o.Value,
|
||||
l: len(o.Value),
|
||||
}
|
||||
}
|
57
vendor/github.com/d5/tengo/objects/array_iterator.go
generated
vendored
Normal file
57
vendor/github.com/d5/tengo/objects/array_iterator.go
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
package objects
|
||||
|
||||
import "github.com/d5/tengo/compiler/token"
|
||||
|
||||
// ArrayIterator is an iterator for an array.
|
||||
type ArrayIterator struct {
|
||||
v []Object
|
||||
i int
|
||||
l int
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (i *ArrayIterator) TypeName() string {
|
||||
return "array-iterator"
|
||||
}
|
||||
|
||||
func (i *ArrayIterator) String() string {
|
||||
return "<array-iterator>"
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (i *ArrayIterator) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (i *ArrayIterator) IsFalsy() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (i *ArrayIterator) Equals(Object) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (i *ArrayIterator) Copy() Object {
|
||||
return &ArrayIterator{v: i.v, i: i.i, l: i.l}
|
||||
}
|
||||
|
||||
// Next returns true if there are more elements to iterate.
|
||||
func (i *ArrayIterator) Next() bool {
|
||||
i.i++
|
||||
return i.i <= i.l
|
||||
}
|
||||
|
||||
// Key returns the key or index value of the current element.
|
||||
func (i *ArrayIterator) Key() Object {
|
||||
return &Int{Value: int64(i.i - 1)}
|
||||
}
|
||||
|
||||
// Value returns the value of the current element.
|
||||
func (i *ArrayIterator) Value() Object {
|
||||
return i.v[i.i-1]
|
||||
}
|
64
vendor/github.com/d5/tengo/objects/bool.go
generated
vendored
Normal file
64
vendor/github.com/d5/tengo/objects/bool.go
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// Bool represents a boolean value.
|
||||
type Bool struct {
|
||||
// this is intentionally non-public to force using objects.TrueValue and FalseValue always
|
||||
value bool
|
||||
}
|
||||
|
||||
func (o *Bool) String() string {
|
||||
if o.value {
|
||||
return "true"
|
||||
}
|
||||
|
||||
return "false"
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *Bool) TypeName() string {
|
||||
return "bool"
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *Bool) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *Bool) Copy() Object {
|
||||
return o
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *Bool) IsFalsy() bool {
|
||||
return !o.value
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *Bool) Equals(x Object) bool {
|
||||
return o == x
|
||||
}
|
||||
|
||||
// GobDecode decodes bool value from input bytes.
|
||||
func (o *Bool) GobDecode(b []byte) (err error) {
|
||||
o.value = b[0] == 1
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GobEncode encodes bool values into bytes.
|
||||
func (o *Bool) GobEncode() (b []byte, err error) {
|
||||
if o.value {
|
||||
b = []byte{1}
|
||||
} else {
|
||||
b = []byte{0}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
37
vendor/github.com/d5/tengo/objects/break.go
generated
vendored
Normal file
37
vendor/github.com/d5/tengo/objects/break.go
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
package objects
|
||||
|
||||
import "github.com/d5/tengo/compiler/token"
|
||||
|
||||
// Break represents a break statement.
|
||||
type Break struct{}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *Break) TypeName() string {
|
||||
return "break"
|
||||
}
|
||||
|
||||
func (o *Break) String() string {
|
||||
return "<break>"
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *Break) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *Break) Copy() Object {
|
||||
return &Break{}
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *Break) IsFalsy() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *Break) Equals(x Object) bool {
|
||||
return false
|
||||
}
|
21
vendor/github.com/d5/tengo/objects/builtin_append.go
generated
vendored
Normal file
21
vendor/github.com/d5/tengo/objects/builtin_append.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
package objects
|
||||
|
||||
// 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(),
|
||||
}
|
||||
}
|
||||
}
|
155
vendor/github.com/d5/tengo/objects/builtin_convert.go
generated
vendored
Normal file
155
vendor/github.com/d5/tengo/objects/builtin_convert.go
generated
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
package objects
|
||||
|
||||
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 {
|
||||
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 {
|
||||
return &Bytes{Value: make([]byte, int(n.Value))}, nil
|
||||
}
|
||||
|
||||
v, ok := ToByteSlice(args[0])
|
||||
if ok {
|
||||
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
|
||||
}
|
9
vendor/github.com/d5/tengo/objects/builtin_copy.go
generated
vendored
Normal file
9
vendor/github.com/d5/tengo/objects/builtin_copy.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
package objects
|
||||
|
||||
func builtinCopy(args ...Object) (Object, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, ErrWrongNumArguments
|
||||
}
|
||||
|
||||
return args[0].Copy(), nil
|
||||
}
|
47
vendor/github.com/d5/tengo/objects/builtin_function.go
generated
vendored
Normal file
47
vendor/github.com/d5/tengo/objects/builtin_function.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// BuiltinFunction represents a builtin function.
|
||||
type BuiltinFunction struct {
|
||||
Name string
|
||||
Value CallableFunc
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *BuiltinFunction) TypeName() string {
|
||||
return "builtin-function:" + o.Name
|
||||
}
|
||||
|
||||
func (o *BuiltinFunction) String() string {
|
||||
return "<builtin-function>"
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *BuiltinFunction) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *BuiltinFunction) Copy() Object {
|
||||
return &BuiltinFunction{Value: o.Value}
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *BuiltinFunction) IsFalsy() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *BuiltinFunction) Equals(x Object) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Call executes a builtin function.
|
||||
func (o *BuiltinFunction) Call(args ...Object) (Object, error) {
|
||||
return o.Value(args...)
|
||||
}
|
54
vendor/github.com/d5/tengo/objects/builtin_json.go
generated
vendored
Normal file
54
vendor/github.com/d5/tengo/objects/builtin_json.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// to_json(v object) => bytes
|
||||
func builtinToJSON(args ...Object) (Object, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, ErrWrongNumArguments
|
||||
}
|
||||
|
||||
res, err := json.Marshal(objectToInterface(args[0]))
|
||||
if err != nil {
|
||||
return &Error{Value: &String{Value: err.Error()}}, nil
|
||||
}
|
||||
|
||||
return &Bytes{Value: res}, nil
|
||||
}
|
||||
|
||||
// from_json(data string/bytes) => object
|
||||
func builtinFromJSON(args ...Object) (Object, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, ErrWrongNumArguments
|
||||
}
|
||||
|
||||
var target interface{}
|
||||
|
||||
switch o := args[0].(type) {
|
||||
case *Bytes:
|
||||
err := json.Unmarshal(o.Value, &target)
|
||||
if err != nil {
|
||||
return &Error{Value: &String{Value: err.Error()}}, nil
|
||||
}
|
||||
case *String:
|
||||
err := json.Unmarshal([]byte(o.Value), &target)
|
||||
if err != nil {
|
||||
return &Error{Value: &String{Value: err.Error()}}, nil
|
||||
}
|
||||
default:
|
||||
return nil, ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "bytes/string",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
|
||||
res, err := FromInterface(target)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
29
vendor/github.com/d5/tengo/objects/builtin_len.go
generated
vendored
Normal file
29
vendor/github.com/d5/tengo/objects/builtin_len.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
package objects
|
||||
|
||||
// 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(),
|
||||
}
|
||||
}
|
||||
}
|
75
vendor/github.com/d5/tengo/objects/builtin_print.go
generated
vendored
Normal file
75
vendor/github.com/d5/tengo/objects/builtin_print.go
generated
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// print(args...)
|
||||
func builtinPrint(args ...Object) (Object, error) {
|
||||
for _, arg := range args {
|
||||
if str, ok := arg.(*String); ok {
|
||||
fmt.Println(str.Value)
|
||||
} else {
|
||||
fmt.Println(arg.String())
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// printf("format", args...)
|
||||
func builtinPrintf(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 {
|
||||
fmt.Print(format)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
formatArgs := make([]interface{}, numArgs-1, numArgs-1)
|
||||
for idx, arg := range args[1:] {
|
||||
formatArgs[idx] = objectToInterface(arg)
|
||||
}
|
||||
|
||||
fmt.Printf(format.Value, formatArgs...)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// sprintf("format", args...)
|
||||
func builtinSprintf(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 {
|
||||
return format, nil // okay to return 'format' directly as String is immutable
|
||||
}
|
||||
|
||||
formatArgs := make([]interface{}, numArgs-1, numArgs-1)
|
||||
for idx, arg := range args[1:] {
|
||||
formatArgs[idx] = objectToInterface(arg)
|
||||
}
|
||||
|
||||
return &String{Value: fmt.Sprintf(format.Value, formatArgs...)}, nil
|
||||
}
|
9
vendor/github.com/d5/tengo/objects/builtin_type.go
generated
vendored
Normal file
9
vendor/github.com/d5/tengo/objects/builtin_type.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
package objects
|
||||
|
||||
func builtinTypeName(args ...Object) (Object, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, ErrWrongNumArguments
|
||||
}
|
||||
|
||||
return &String{Value: args[0].TypeName()}, nil
|
||||
}
|
183
vendor/github.com/d5/tengo/objects/builtin_type_checks.go
generated
vendored
Normal file
183
vendor/github.com/d5/tengo/objects/builtin_type_checks.go
generated
vendored
Normal file
@ -0,0 +1,183 @@
|
||||
package objects
|
||||
|
||||
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, *Closure:
|
||||
return TrueValue, nil
|
||||
}
|
||||
|
||||
return FalseValue, nil
|
||||
}
|
||||
|
||||
func builtinIsCallable(args ...Object) (Object, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, ErrWrongNumArguments
|
||||
}
|
||||
|
||||
switch args[0].(type) {
|
||||
case *CompiledFunction, *Closure, Callable: // BuiltinFunction is Callable
|
||||
return TrueValue, nil
|
||||
}
|
||||
|
||||
return FalseValue, nil
|
||||
}
|
135
vendor/github.com/d5/tengo/objects/builtins.go
generated
vendored
Normal file
135
vendor/github.com/d5/tengo/objects/builtins.go
generated
vendored
Normal file
@ -0,0 +1,135 @@
|
||||
package objects
|
||||
|
||||
// NamedBuiltinFunc is a named builtin function.
|
||||
type NamedBuiltinFunc struct {
|
||||
Name string
|
||||
Func CallableFunc
|
||||
}
|
||||
|
||||
// Builtins contains all default builtin functions.
|
||||
var Builtins = []NamedBuiltinFunc{
|
||||
{
|
||||
Name: "print",
|
||||
Func: builtinPrint,
|
||||
},
|
||||
{
|
||||
Name: "printf",
|
||||
Func: builtinPrintf,
|
||||
},
|
||||
{
|
||||
Name: "sprintf",
|
||||
Func: builtinSprintf,
|
||||
},
|
||||
{
|
||||
Name: "len",
|
||||
Func: builtinLen,
|
||||
},
|
||||
{
|
||||
Name: "copy",
|
||||
Func: builtinCopy,
|
||||
},
|
||||
{
|
||||
Name: "append",
|
||||
Func: builtinAppend,
|
||||
},
|
||||
{
|
||||
Name: "string",
|
||||
Func: builtinString,
|
||||
},
|
||||
{
|
||||
Name: "int",
|
||||
Func: builtinInt,
|
||||
},
|
||||
{
|
||||
Name: "bool",
|
||||
Func: builtinBool,
|
||||
},
|
||||
{
|
||||
Name: "float",
|
||||
Func: builtinFloat,
|
||||
},
|
||||
{
|
||||
Name: "char",
|
||||
Func: builtinChar,
|
||||
},
|
||||
{
|
||||
Name: "bytes",
|
||||
Func: builtinBytes,
|
||||
},
|
||||
{
|
||||
Name: "time",
|
||||
Func: builtinTime,
|
||||
},
|
||||
{
|
||||
Name: "is_int",
|
||||
Func: builtinIsInt,
|
||||
},
|
||||
{
|
||||
Name: "is_float",
|
||||
Func: builtinIsFloat,
|
||||
},
|
||||
{
|
||||
Name: "is_string",
|
||||
Func: builtinIsString,
|
||||
},
|
||||
{
|
||||
Name: "is_bool",
|
||||
Func: builtinIsBool,
|
||||
},
|
||||
{
|
||||
Name: "is_char",
|
||||
Func: builtinIsChar,
|
||||
},
|
||||
{
|
||||
Name: "is_bytes",
|
||||
Func: builtinIsBytes,
|
||||
},
|
||||
{
|
||||
Name: "is_array",
|
||||
Func: builtinIsArray,
|
||||
},
|
||||
{
|
||||
Name: "is_immutable_array",
|
||||
Func: builtinIsImmutableArray,
|
||||
},
|
||||
{
|
||||
Name: "is_map",
|
||||
Func: builtinIsMap,
|
||||
},
|
||||
{
|
||||
Name: "is_immutable_map",
|
||||
Func: builtinIsImmutableMap,
|
||||
},
|
||||
{
|
||||
Name: "is_time",
|
||||
Func: builtinIsTime,
|
||||
},
|
||||
{
|
||||
Name: "is_error",
|
||||
Func: builtinIsError,
|
||||
},
|
||||
{
|
||||
Name: "is_undefined",
|
||||
Func: builtinIsUndefined,
|
||||
},
|
||||
{
|
||||
Name: "is_function",
|
||||
Func: builtinIsFunction,
|
||||
},
|
||||
{
|
||||
Name: "is_callable",
|
||||
Func: builtinIsCallable,
|
||||
},
|
||||
{
|
||||
Name: "to_json",
|
||||
Func: builtinToJSON,
|
||||
},
|
||||
{
|
||||
Name: "from_json",
|
||||
Func: builtinFromJSON,
|
||||
},
|
||||
{
|
||||
Name: "type_name",
|
||||
Func: builtinTypeName,
|
||||
},
|
||||
}
|
76
vendor/github.com/d5/tengo/objects/bytes.go
generated
vendored
Normal file
76
vendor/github.com/d5/tengo/objects/bytes.go
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// Bytes represents a byte array.
|
||||
type Bytes struct {
|
||||
Value []byte
|
||||
}
|
||||
|
||||
func (o *Bytes) String() string {
|
||||
return string(o.Value)
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *Bytes) TypeName() string {
|
||||
return "bytes"
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *Bytes) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
switch op {
|
||||
case token.Add:
|
||||
switch rhs := rhs.(type) {
|
||||
case *Bytes:
|
||||
return &Bytes{Value: append(o.Value, rhs.Value...)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *Bytes) Copy() Object {
|
||||
return &Bytes{Value: append([]byte{}, o.Value...)}
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *Bytes) IsFalsy() bool {
|
||||
return len(o.Value) == 0
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *Bytes) Equals(x Object) bool {
|
||||
t, ok := x.(*Bytes)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return bytes.Compare(o.Value, t.Value) == 0
|
||||
}
|
||||
|
||||
// IndexGet returns an element (as Int) at a given index.
|
||||
func (o *Bytes) IndexGet(index Object) (res Object, err error) {
|
||||
intIdx, ok := index.(*Int)
|
||||
if !ok {
|
||||
err = ErrInvalidIndexType
|
||||
return
|
||||
}
|
||||
|
||||
idxVal := int(intIdx.Value)
|
||||
|
||||
if idxVal < 0 || idxVal >= len(o.Value) {
|
||||
res = UndefinedValue
|
||||
return
|
||||
}
|
||||
|
||||
res = &Int{Value: int64(o.Value[idxVal])}
|
||||
|
||||
return
|
||||
}
|
9
vendor/github.com/d5/tengo/objects/callable.go
generated
vendored
Normal file
9
vendor/github.com/d5/tengo/objects/callable.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
package objects
|
||||
|
||||
// Callable represents an object that can be called like a function.
|
||||
type Callable interface {
|
||||
// Call should take an arbitrary number of arguments
|
||||
// and returns a return value and/or an error,
|
||||
// which the VM will consider as a run-time error.
|
||||
Call(args ...Object) (ret Object, err error)
|
||||
}
|
4
vendor/github.com/d5/tengo/objects/callable_func.go
generated
vendored
Normal file
4
vendor/github.com/d5/tengo/objects/callable_func.go
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
package objects
|
||||
|
||||
// CallableFunc is a function signature for the callable functions.
|
||||
type CallableFunc func(args ...Object) (ret Object, err error)
|
119
vendor/github.com/d5/tengo/objects/char.go
generated
vendored
Normal file
119
vendor/github.com/d5/tengo/objects/char.go
generated
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// Char represents a character value.
|
||||
type Char struct {
|
||||
Value rune
|
||||
}
|
||||
|
||||
func (o *Char) String() string {
|
||||
return string(o.Value)
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *Char) TypeName() string {
|
||||
return "char"
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *Char) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
switch rhs := rhs.(type) {
|
||||
case *Char:
|
||||
switch op {
|
||||
case token.Add:
|
||||
r := o.Value + rhs.Value
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Char{Value: r}, nil
|
||||
case token.Sub:
|
||||
r := o.Value - rhs.Value
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Char{Value: r}, nil
|
||||
case token.Less:
|
||||
if o.Value < rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.Greater:
|
||||
if o.Value > rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.LessEq:
|
||||
if o.Value <= rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.GreaterEq:
|
||||
if o.Value >= rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
}
|
||||
case *Int:
|
||||
switch op {
|
||||
case token.Add:
|
||||
r := o.Value + rune(rhs.Value)
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Char{Value: r}, nil
|
||||
case token.Sub:
|
||||
r := o.Value - rune(rhs.Value)
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Char{Value: r}, nil
|
||||
case token.Less:
|
||||
if int64(o.Value) < rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.Greater:
|
||||
if int64(o.Value) > rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.LessEq:
|
||||
if int64(o.Value) <= rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.GreaterEq:
|
||||
if int64(o.Value) >= rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *Char) Copy() Object {
|
||||
return &Char{Value: o.Value}
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *Char) IsFalsy() bool {
|
||||
return o.Value == 0
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *Char) Equals(x Object) bool {
|
||||
t, ok := x.(*Char)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return o.Value == t.Value
|
||||
}
|
45
vendor/github.com/d5/tengo/objects/closure.go
generated
vendored
Normal file
45
vendor/github.com/d5/tengo/objects/closure.go
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// Closure represents a function closure.
|
||||
type Closure struct {
|
||||
Fn *CompiledFunction
|
||||
Free []*Object
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *Closure) TypeName() string {
|
||||
return "closure"
|
||||
}
|
||||
|
||||
func (o *Closure) String() string {
|
||||
return "<closure>"
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *Closure) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *Closure) Copy() Object {
|
||||
return &Closure{
|
||||
Fn: o.Fn.Copy().(*CompiledFunction),
|
||||
Free: append([]*Object{}, o.Free...), // DO NOT Copy() of elements; these are variable pointers
|
||||
}
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *Closure) IsFalsy() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *Closure) Equals(x Object) bool {
|
||||
return false
|
||||
}
|
49
vendor/github.com/d5/tengo/objects/compiled_function.go
generated
vendored
Normal file
49
vendor/github.com/d5/tengo/objects/compiled_function.go
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"github.com/d5/tengo/compiler/source"
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// CompiledFunction represents a compiled function.
|
||||
type CompiledFunction struct {
|
||||
Instructions []byte
|
||||
NumLocals int // number of local variables (including function parameters)
|
||||
NumParameters int
|
||||
SourceMap map[int]source.Pos
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *CompiledFunction) TypeName() string {
|
||||
return "compiled-function"
|
||||
}
|
||||
|
||||
func (o *CompiledFunction) String() string {
|
||||
return "<compiled-function>"
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *CompiledFunction) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *CompiledFunction) Copy() Object {
|
||||
return &CompiledFunction{
|
||||
Instructions: append([]byte{}, o.Instructions...),
|
||||
NumLocals: o.NumLocals,
|
||||
NumParameters: o.NumParameters,
|
||||
}
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *CompiledFunction) IsFalsy() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *CompiledFunction) Equals(x Object) bool {
|
||||
return false
|
||||
}
|
38
vendor/github.com/d5/tengo/objects/continue.go
generated
vendored
Normal file
38
vendor/github.com/d5/tengo/objects/continue.go
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
package objects
|
||||
|
||||
import "github.com/d5/tengo/compiler/token"
|
||||
|
||||
// Continue represents a continue statement.
|
||||
type Continue struct {
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *Continue) TypeName() string {
|
||||
return "continue"
|
||||
}
|
||||
|
||||
func (o *Continue) String() string {
|
||||
return "<continue>"
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *Continue) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *Continue) Copy() Object {
|
||||
return &Continue{}
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *Continue) IsFalsy() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *Continue) Equals(x Object) bool {
|
||||
return false
|
||||
}
|
249
vendor/github.com/d5/tengo/objects/conversion.go
generated
vendored
Normal file
249
vendor/github.com/d5/tengo/objects/conversion.go
generated
vendored
Normal file
@ -0,0 +1,249 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ToString will try to convert object o to string value.
|
||||
func ToString(o Object) (v string, ok bool) {
|
||||
if o == UndefinedValue {
|
||||
//ok = false
|
||||
return
|
||||
}
|
||||
|
||||
ok = true
|
||||
|
||||
if str, isStr := o.(*String); isStr {
|
||||
v = str.Value
|
||||
} else {
|
||||
v = o.String()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ToInt will try to convert object o to int value.
|
||||
func ToInt(o Object) (v int, ok bool) {
|
||||
switch o := o.(type) {
|
||||
case *Int:
|
||||
v = int(o.Value)
|
||||
ok = true
|
||||
case *Float:
|
||||
v = int(o.Value)
|
||||
ok = true
|
||||
case *Char:
|
||||
v = int(o.Value)
|
||||
ok = true
|
||||
case *Bool:
|
||||
if o == TrueValue {
|
||||
v = 1
|
||||
}
|
||||
ok = true
|
||||
case *String:
|
||||
c, err := strconv.ParseInt(o.Value, 10, 64)
|
||||
if err == nil {
|
||||
v = int(c)
|
||||
ok = true
|
||||
}
|
||||
}
|
||||
|
||||
//ok = false
|
||||
return
|
||||
}
|
||||
|
||||
// ToInt64 will try to convert object o to int64 value.
|
||||
func ToInt64(o Object) (v int64, ok bool) {
|
||||
switch o := o.(type) {
|
||||
case *Int:
|
||||
v = o.Value
|
||||
ok = true
|
||||
case *Float:
|
||||
v = int64(o.Value)
|
||||
ok = true
|
||||
case *Char:
|
||||
v = int64(o.Value)
|
||||
ok = true
|
||||
case *Bool:
|
||||
if o == TrueValue {
|
||||
v = 1
|
||||
}
|
||||
ok = true
|
||||
case *String:
|
||||
c, err := strconv.ParseInt(o.Value, 10, 64)
|
||||
if err == nil {
|
||||
v = c
|
||||
ok = true
|
||||
}
|
||||
}
|
||||
|
||||
//ok = false
|
||||
return
|
||||
}
|
||||
|
||||
// ToFloat64 will try to convert object o to float64 value.
|
||||
func ToFloat64(o Object) (v float64, ok bool) {
|
||||
switch o := o.(type) {
|
||||
case *Int:
|
||||
v = float64(o.Value)
|
||||
ok = true
|
||||
case *Float:
|
||||
v = o.Value
|
||||
ok = true
|
||||
case *String:
|
||||
c, err := strconv.ParseFloat(o.Value, 64)
|
||||
if err == nil {
|
||||
v = c
|
||||
ok = true
|
||||
}
|
||||
}
|
||||
|
||||
//ok = false
|
||||
return
|
||||
}
|
||||
|
||||
// ToBool will try to convert object o to bool value.
|
||||
func ToBool(o Object) (v bool, ok bool) {
|
||||
ok = true
|
||||
v = !o.IsFalsy()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ToRune will try to convert object o to rune value.
|
||||
func ToRune(o Object) (v rune, ok bool) {
|
||||
switch o := o.(type) {
|
||||
case *Int:
|
||||
v = rune(o.Value)
|
||||
ok = true
|
||||
case *Char:
|
||||
v = rune(o.Value)
|
||||
ok = true
|
||||
}
|
||||
|
||||
//ok = false
|
||||
return
|
||||
}
|
||||
|
||||
// ToByteSlice will try to convert object o to []byte value.
|
||||
func ToByteSlice(o Object) (v []byte, ok bool) {
|
||||
switch o := o.(type) {
|
||||
case *Bytes:
|
||||
v = o.Value
|
||||
ok = true
|
||||
case *String:
|
||||
v = []byte(o.Value)
|
||||
ok = true
|
||||
}
|
||||
|
||||
//ok = false
|
||||
return
|
||||
}
|
||||
|
||||
// ToTime will try to convert object o to time.Time value.
|
||||
func ToTime(o Object) (v time.Time, ok bool) {
|
||||
switch o := o.(type) {
|
||||
case *Time:
|
||||
v = o.Value
|
||||
ok = true
|
||||
case *Int:
|
||||
v = time.Unix(o.Value, 0)
|
||||
ok = true
|
||||
}
|
||||
|
||||
//ok = false
|
||||
return
|
||||
}
|
||||
|
||||
// objectToInterface attempts to convert an object o to an interface{} value
|
||||
func objectToInterface(o Object) (res interface{}) {
|
||||
switch o := o.(type) {
|
||||
case *Int:
|
||||
res = o.Value
|
||||
case *String:
|
||||
res = o.Value
|
||||
case *Float:
|
||||
res = o.Value
|
||||
case *Bool:
|
||||
res = o == TrueValue
|
||||
case *Char:
|
||||
res = o.Value
|
||||
case *Bytes:
|
||||
res = o.Value
|
||||
case *Array:
|
||||
res = make([]interface{}, len(o.Value))
|
||||
for i, val := range o.Value {
|
||||
res.([]interface{})[i] = objectToInterface(val)
|
||||
}
|
||||
case *Map:
|
||||
res = make(map[string]interface{})
|
||||
for key, v := range o.Value {
|
||||
res.(map[string]interface{})[key] = objectToInterface(v)
|
||||
}
|
||||
case Object:
|
||||
return o
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FromInterface will attempt to convert an interface{} v to a Tengo Object
|
||||
func FromInterface(v interface{}) (Object, error) {
|
||||
switch v := v.(type) {
|
||||
case nil:
|
||||
return UndefinedValue, nil
|
||||
case string:
|
||||
return &String{Value: v}, nil
|
||||
case int64:
|
||||
return &Int{Value: v}, nil
|
||||
case int:
|
||||
return &Int{Value: int64(v)}, nil
|
||||
case bool:
|
||||
if v {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case rune:
|
||||
return &Char{Value: v}, nil
|
||||
case byte:
|
||||
return &Char{Value: rune(v)}, nil
|
||||
case float64:
|
||||
return &Float{Value: v}, nil
|
||||
case []byte:
|
||||
return &Bytes{Value: v}, nil
|
||||
case error:
|
||||
return &Error{Value: &String{Value: v.Error()}}, nil
|
||||
case map[string]Object:
|
||||
return &Map{Value: v}, nil
|
||||
case map[string]interface{}:
|
||||
kv := make(map[string]Object)
|
||||
for vk, vv := range v {
|
||||
vo, err := FromInterface(vv)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kv[vk] = vo
|
||||
}
|
||||
return &Map{Value: kv}, nil
|
||||
case []Object:
|
||||
return &Array{Value: v}, nil
|
||||
case []interface{}:
|
||||
arr := make([]Object, len(v), len(v))
|
||||
for i, e := range v {
|
||||
vo, err := FromInterface(e)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
arr[i] = vo
|
||||
}
|
||||
return &Array{Value: arr}, nil
|
||||
case time.Time:
|
||||
return &Time{Value: v}, nil
|
||||
case Object:
|
||||
return v, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("cannot convert to object: %T", v)
|
||||
}
|
47
vendor/github.com/d5/tengo/objects/error.go
generated
vendored
Normal file
47
vendor/github.com/d5/tengo/objects/error.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// Error represents a string value.
|
||||
type Error struct {
|
||||
Value Object
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *Error) TypeName() string {
|
||||
return "error"
|
||||
}
|
||||
|
||||
func (o *Error) String() string {
|
||||
if o.Value != nil {
|
||||
return fmt.Sprintf("error: %s", o.Value.String())
|
||||
}
|
||||
|
||||
return "error"
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *Error) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *Error) IsFalsy() bool {
|
||||
return true // error is always false.
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *Error) Copy() Object {
|
||||
return &Error{Value: o.Value.Copy()}
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *Error) Equals(x Object) bool {
|
||||
return o == x // pointer equality
|
||||
}
|
32
vendor/github.com/d5/tengo/objects/errors.go
generated
vendored
Normal file
32
vendor/github.com/d5/tengo/objects/errors.go
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ErrIndexOutOfBounds is an error where a given index is out of the bounds.
|
||||
var ErrIndexOutOfBounds = errors.New("index out of bounds")
|
||||
|
||||
// ErrInvalidIndexType represents an invalid index type.
|
||||
var ErrInvalidIndexType = errors.New("invalid index type")
|
||||
|
||||
// ErrInvalidIndexValueType represents an invalid index value type.
|
||||
var ErrInvalidIndexValueType = errors.New("invalid index value type")
|
||||
|
||||
// ErrInvalidOperator represents an error for invalid operator usage.
|
||||
var ErrInvalidOperator = errors.New("invalid operator")
|
||||
|
||||
// ErrWrongNumArguments represents a wrong number of arguments error.
|
||||
var ErrWrongNumArguments = errors.New("wrong number of arguments")
|
||||
|
||||
// ErrInvalidArgumentType represents an invalid argument value type error.
|
||||
type ErrInvalidArgumentType struct {
|
||||
Name string
|
||||
Expected string
|
||||
Found string
|
||||
}
|
||||
|
||||
func (e ErrInvalidArgumentType) Error() string {
|
||||
return fmt.Sprintf("invalid type for argument '%s': expected %s, found %s", e.Name, e.Expected, e.Found)
|
||||
}
|
146
vendor/github.com/d5/tengo/objects/float.go
generated
vendored
Normal file
146
vendor/github.com/d5/tengo/objects/float.go
generated
vendored
Normal file
@ -0,0 +1,146 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strconv"
|
||||
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// Float represents a floating point number value.
|
||||
type Float struct {
|
||||
Value float64
|
||||
}
|
||||
|
||||
func (o *Float) String() string {
|
||||
return strconv.FormatFloat(o.Value, 'f', -1, 64)
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *Float) TypeName() string {
|
||||
return "float"
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *Float) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
switch rhs := rhs.(type) {
|
||||
case *Float:
|
||||
switch op {
|
||||
case token.Add:
|
||||
r := o.Value + rhs.Value
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Float{Value: r}, nil
|
||||
case token.Sub:
|
||||
r := o.Value - rhs.Value
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Float{Value: r}, nil
|
||||
case token.Mul:
|
||||
r := o.Value * rhs.Value
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Float{Value: r}, nil
|
||||
case token.Quo:
|
||||
r := o.Value / rhs.Value
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Float{Value: r}, nil
|
||||
case token.Less:
|
||||
if o.Value < rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.Greater:
|
||||
if o.Value > rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.LessEq:
|
||||
if o.Value <= rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.GreaterEq:
|
||||
if o.Value >= rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
}
|
||||
case *Int:
|
||||
switch op {
|
||||
case token.Add:
|
||||
r := o.Value + float64(rhs.Value)
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Float{Value: r}, nil
|
||||
case token.Sub:
|
||||
r := o.Value - float64(rhs.Value)
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Float{Value: r}, nil
|
||||
case token.Mul:
|
||||
r := o.Value * float64(rhs.Value)
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Float{Value: r}, nil
|
||||
case token.Quo:
|
||||
r := o.Value / float64(rhs.Value)
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Float{Value: r}, nil
|
||||
case token.Less:
|
||||
if o.Value < float64(rhs.Value) {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.Greater:
|
||||
if o.Value > float64(rhs.Value) {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.LessEq:
|
||||
if o.Value <= float64(rhs.Value) {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.GreaterEq:
|
||||
if o.Value >= float64(rhs.Value) {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *Float) Copy() Object {
|
||||
return &Float{Value: o.Value}
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *Float) IsFalsy() bool {
|
||||
return math.IsNaN(o.Value)
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *Float) Equals(x Object) bool {
|
||||
t, ok := x.(*Float)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return o.Value == t.Value
|
||||
}
|
109
vendor/github.com/d5/tengo/objects/immautable_array.go
generated
vendored
Normal file
109
vendor/github.com/d5/tengo/objects/immautable_array.go
generated
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// ImmutableArray represents an immutable array of objects.
|
||||
type ImmutableArray struct {
|
||||
Value []Object
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *ImmutableArray) TypeName() string {
|
||||
return "immutable-array"
|
||||
}
|
||||
|
||||
func (o *ImmutableArray) String() string {
|
||||
var elements []string
|
||||
for _, e := range o.Value {
|
||||
elements = append(elements, e.String())
|
||||
}
|
||||
|
||||
return fmt.Sprintf("[%s]", strings.Join(elements, ", "))
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *ImmutableArray) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
if rhs, ok := rhs.(*ImmutableArray); ok {
|
||||
switch op {
|
||||
case token.Add:
|
||||
return &Array{Value: append(o.Value, rhs.Value...)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *ImmutableArray) Copy() Object {
|
||||
var c []Object
|
||||
for _, elem := range o.Value {
|
||||
c = append(c, elem.Copy())
|
||||
}
|
||||
|
||||
return &Array{Value: c}
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *ImmutableArray) IsFalsy() bool {
|
||||
return len(o.Value) == 0
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *ImmutableArray) Equals(x Object) bool {
|
||||
var xVal []Object
|
||||
switch x := x.(type) {
|
||||
case *Array:
|
||||
xVal = x.Value
|
||||
case *ImmutableArray:
|
||||
xVal = x.Value
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
if len(o.Value) != len(xVal) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i, e := range o.Value {
|
||||
if !e.Equals(xVal[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// IndexGet returns an element at a given index.
|
||||
func (o *ImmutableArray) IndexGet(index Object) (res Object, err error) {
|
||||
intIdx, ok := index.(*Int)
|
||||
if !ok {
|
||||
err = ErrInvalidIndexType
|
||||
return
|
||||
}
|
||||
|
||||
idxVal := int(intIdx.Value)
|
||||
|
||||
if idxVal < 0 || idxVal >= len(o.Value) {
|
||||
res = UndefinedValue
|
||||
return
|
||||
}
|
||||
|
||||
res = o.Value[idxVal]
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Iterate creates an array iterator.
|
||||
func (o *ImmutableArray) Iterate() Iterator {
|
||||
return &ArrayIterator{
|
||||
v: o.Value,
|
||||
l: len(o.Value),
|
||||
}
|
||||
}
|
105
vendor/github.com/d5/tengo/objects/immutable_map.go
generated
vendored
Normal file
105
vendor/github.com/d5/tengo/objects/immutable_map.go
generated
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// ImmutableMap represents an immutable map object.
|
||||
type ImmutableMap struct {
|
||||
Value map[string]Object
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *ImmutableMap) TypeName() string {
|
||||
return "immutable-map"
|
||||
}
|
||||
|
||||
func (o *ImmutableMap) String() string {
|
||||
var pairs []string
|
||||
for k, v := range o.Value {
|
||||
pairs = append(pairs, fmt.Sprintf("%s: %s", k, v.String()))
|
||||
}
|
||||
|
||||
return fmt.Sprintf("{%s}", strings.Join(pairs, ", "))
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *ImmutableMap) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *ImmutableMap) Copy() Object {
|
||||
c := make(map[string]Object)
|
||||
for k, v := range o.Value {
|
||||
c[k] = v.Copy()
|
||||
}
|
||||
|
||||
return &Map{Value: c}
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *ImmutableMap) IsFalsy() bool {
|
||||
return len(o.Value) == 0
|
||||
}
|
||||
|
||||
// IndexGet returns the value for the given key.
|
||||
func (o *ImmutableMap) IndexGet(index Object) (res Object, err error) {
|
||||
strIdx, ok := ToString(index)
|
||||
if !ok {
|
||||
err = ErrInvalidIndexType
|
||||
return
|
||||
}
|
||||
|
||||
val, ok := o.Value[strIdx]
|
||||
if !ok {
|
||||
val = UndefinedValue
|
||||
}
|
||||
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *ImmutableMap) Equals(x Object) bool {
|
||||
var xVal map[string]Object
|
||||
switch x := x.(type) {
|
||||
case *Map:
|
||||
xVal = x.Value
|
||||
case *ImmutableMap:
|
||||
xVal = x.Value
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
if len(o.Value) != len(xVal) {
|
||||
return false
|
||||
}
|
||||
|
||||
for k, v := range o.Value {
|
||||
tv := xVal[k]
|
||||
if !v.Equals(tv) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Iterate creates an immutable map iterator.
|
||||
func (o *ImmutableMap) Iterate() Iterator {
|
||||
var keys []string
|
||||
for k := range o.Value {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
return &MapIterator{
|
||||
v: o.Value,
|
||||
k: keys,
|
||||
l: len(keys),
|
||||
}
|
||||
}
|
9
vendor/github.com/d5/tengo/objects/index_assignable.go
generated
vendored
Normal file
9
vendor/github.com/d5/tengo/objects/index_assignable.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
package objects
|
||||
|
||||
// IndexAssignable is an object that can take an index and a value
|
||||
// on the left-hand side of the assignment statement.
|
||||
type IndexAssignable interface {
|
||||
// IndexSet should take an index Object and a value Object.
|
||||
// If an error is returned, it will be treated as a run-time error.
|
||||
IndexSet(index, value Object) error
|
||||
}
|
9
vendor/github.com/d5/tengo/objects/indexable.go
generated
vendored
Normal file
9
vendor/github.com/d5/tengo/objects/indexable.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
package objects
|
||||
|
||||
// Indexable is an object that can take an index and return an object.
|
||||
type Indexable interface {
|
||||
// IndexGet should take an index Object and return a result Object or an error.
|
||||
// If error is returned, the runtime will treat it as a run-time error and ignore returned value.
|
||||
// If nil is returned as value, it will be converted to Undefined value by the runtime.
|
||||
IndexGet(index Object) (value Object, err error)
|
||||
}
|
198
vendor/github.com/d5/tengo/objects/int.go
generated
vendored
Normal file
198
vendor/github.com/d5/tengo/objects/int.go
generated
vendored
Normal file
@ -0,0 +1,198 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// Int represents an integer value.
|
||||
type Int struct {
|
||||
Value int64
|
||||
}
|
||||
|
||||
func (o *Int) String() string {
|
||||
return strconv.FormatInt(o.Value, 10)
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *Int) TypeName() string {
|
||||
return "int"
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *Int) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
switch rhs := rhs.(type) {
|
||||
case *Int:
|
||||
switch op {
|
||||
case token.Add:
|
||||
r := o.Value + rhs.Value
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Int{Value: r}, nil
|
||||
case token.Sub:
|
||||
r := o.Value - rhs.Value
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Int{Value: r}, nil
|
||||
case token.Mul:
|
||||
r := o.Value * rhs.Value
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Int{Value: r}, nil
|
||||
case token.Quo:
|
||||
r := o.Value / rhs.Value
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Int{Value: r}, nil
|
||||
case token.Rem:
|
||||
r := o.Value % rhs.Value
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Int{Value: r}, nil
|
||||
case token.And:
|
||||
r := o.Value & rhs.Value
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Int{Value: r}, nil
|
||||
case token.Or:
|
||||
r := o.Value | rhs.Value
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Int{Value: r}, nil
|
||||
case token.Xor:
|
||||
r := o.Value ^ rhs.Value
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Int{Value: r}, nil
|
||||
case token.AndNot:
|
||||
r := o.Value &^ rhs.Value
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Int{Value: r}, nil
|
||||
case token.Shl:
|
||||
r := o.Value << uint64(rhs.Value)
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Int{Value: r}, nil
|
||||
case token.Shr:
|
||||
r := o.Value >> uint64(rhs.Value)
|
||||
if r == o.Value {
|
||||
return o, nil
|
||||
}
|
||||
return &Int{Value: r}, nil
|
||||
case token.Less:
|
||||
if o.Value < rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.Greater:
|
||||
if o.Value > rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.LessEq:
|
||||
if o.Value <= rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.GreaterEq:
|
||||
if o.Value >= rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
}
|
||||
case *Float:
|
||||
switch op {
|
||||
case token.Add:
|
||||
return &Float{float64(o.Value) + rhs.Value}, nil
|
||||
case token.Sub:
|
||||
return &Float{float64(o.Value) - rhs.Value}, nil
|
||||
case token.Mul:
|
||||
return &Float{float64(o.Value) * rhs.Value}, nil
|
||||
case token.Quo:
|
||||
return &Float{float64(o.Value) / rhs.Value}, nil
|
||||
case token.Less:
|
||||
if float64(o.Value) < rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.Greater:
|
||||
if float64(o.Value) > rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.LessEq:
|
||||
if float64(o.Value) <= rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.GreaterEq:
|
||||
if float64(o.Value) >= rhs.Value {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
}
|
||||
case *Char:
|
||||
switch op {
|
||||
case token.Add:
|
||||
return &Char{rune(o.Value) + rhs.Value}, nil
|
||||
case token.Sub:
|
||||
return &Char{rune(o.Value) - rhs.Value}, nil
|
||||
case token.Less:
|
||||
if o.Value < int64(rhs.Value) {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.Greater:
|
||||
if o.Value > int64(rhs.Value) {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.LessEq:
|
||||
if o.Value <= int64(rhs.Value) {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.GreaterEq:
|
||||
if o.Value >= int64(rhs.Value) {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *Int) Copy() Object {
|
||||
return &Int{Value: o.Value}
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *Int) IsFalsy() bool {
|
||||
return o.Value == 0
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *Int) Equals(x Object) bool {
|
||||
t, ok := x.(*Int)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return o.Value == t.Value
|
||||
}
|
7
vendor/github.com/d5/tengo/objects/iterable.go
generated
vendored
Normal file
7
vendor/github.com/d5/tengo/objects/iterable.go
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
package objects
|
||||
|
||||
// Iterable represents an object that has iterator.
|
||||
type Iterable interface {
|
||||
// Iterate should return an Iterator for the type.
|
||||
Iterate() Iterator
|
||||
}
|
15
vendor/github.com/d5/tengo/objects/iterator.go
generated
vendored
Normal file
15
vendor/github.com/d5/tengo/objects/iterator.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
package objects
|
||||
|
||||
// Iterator represents an iterator for underlying data type.
|
||||
type Iterator interface {
|
||||
Object
|
||||
|
||||
// Next returns true if there are more elements to iterate.
|
||||
Next() bool
|
||||
|
||||
// Key returns the key or index value of the current element.
|
||||
Key() Object
|
||||
|
||||
// Value returns the value of the current element.
|
||||
Value() Object
|
||||
}
|
118
vendor/github.com/d5/tengo/objects/map.go
generated
vendored
Normal file
118
vendor/github.com/d5/tengo/objects/map.go
generated
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// Map represents a map of objects.
|
||||
type Map struct {
|
||||
Value map[string]Object
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *Map) TypeName() string {
|
||||
return "map"
|
||||
}
|
||||
|
||||
func (o *Map) String() string {
|
||||
var pairs []string
|
||||
for k, v := range o.Value {
|
||||
pairs = append(pairs, fmt.Sprintf("%s: %s", k, v.String()))
|
||||
}
|
||||
|
||||
return fmt.Sprintf("{%s}", strings.Join(pairs, ", "))
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *Map) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *Map) Copy() Object {
|
||||
c := make(map[string]Object)
|
||||
for k, v := range o.Value {
|
||||
c[k] = v.Copy()
|
||||
}
|
||||
|
||||
return &Map{Value: c}
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *Map) IsFalsy() bool {
|
||||
return len(o.Value) == 0
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *Map) Equals(x Object) bool {
|
||||
var xVal map[string]Object
|
||||
switch x := x.(type) {
|
||||
case *Map:
|
||||
xVal = x.Value
|
||||
case *ImmutableMap:
|
||||
xVal = x.Value
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
if len(o.Value) != len(xVal) {
|
||||
return false
|
||||
}
|
||||
|
||||
for k, v := range o.Value {
|
||||
tv := xVal[k]
|
||||
if !v.Equals(tv) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// IndexGet returns the value for the given key.
|
||||
func (o *Map) IndexGet(index Object) (res Object, err error) {
|
||||
strIdx, ok := index.(*String)
|
||||
if !ok {
|
||||
err = ErrInvalidIndexType
|
||||
return
|
||||
}
|
||||
|
||||
val, ok := o.Value[strIdx.Value]
|
||||
if !ok {
|
||||
val = UndefinedValue
|
||||
}
|
||||
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// IndexSet sets the value for the given key.
|
||||
func (o *Map) IndexSet(index, value Object) (err error) {
|
||||
strIdx, ok := ToString(index)
|
||||
if !ok {
|
||||
err = ErrInvalidIndexType
|
||||
return
|
||||
}
|
||||
|
||||
o.Value[strIdx] = value
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Iterate creates a map iterator.
|
||||
func (o *Map) Iterate() Iterator {
|
||||
var keys []string
|
||||
for k := range o.Value {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
return &MapIterator{
|
||||
v: o.Value,
|
||||
k: keys,
|
||||
l: len(keys),
|
||||
}
|
||||
}
|
62
vendor/github.com/d5/tengo/objects/map_iterator.go
generated
vendored
Normal file
62
vendor/github.com/d5/tengo/objects/map_iterator.go
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
package objects
|
||||
|
||||
import "github.com/d5/tengo/compiler/token"
|
||||
|
||||
// MapIterator represents an iterator for the map.
|
||||
type MapIterator struct {
|
||||
v map[string]Object
|
||||
k []string
|
||||
i int
|
||||
l int
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (i *MapIterator) TypeName() string {
|
||||
return "map-iterator"
|
||||
}
|
||||
|
||||
func (i *MapIterator) String() string {
|
||||
return "<map-iterator>"
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (i *MapIterator) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (i *MapIterator) IsFalsy() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (i *MapIterator) Equals(Object) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (i *MapIterator) Copy() Object {
|
||||
return &MapIterator{v: i.v, k: i.k, i: i.i, l: i.l}
|
||||
}
|
||||
|
||||
// Next returns true if there are more elements to iterate.
|
||||
func (i *MapIterator) Next() bool {
|
||||
i.i++
|
||||
return i.i <= i.l
|
||||
}
|
||||
|
||||
// Key returns the key or index value of the current element.
|
||||
func (i *MapIterator) Key() Object {
|
||||
k := i.k[i.i-1]
|
||||
|
||||
return &String{Value: k}
|
||||
}
|
||||
|
||||
// Value returns the value of the current element.
|
||||
func (i *MapIterator) Value() Object {
|
||||
k := i.k[i.i-1]
|
||||
|
||||
return i.v[k]
|
||||
}
|
30
vendor/github.com/d5/tengo/objects/object.go
generated
vendored
Normal file
30
vendor/github.com/d5/tengo/objects/object.go
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
package objects
|
||||
|
||||
import "github.com/d5/tengo/compiler/token"
|
||||
|
||||
// Object represents an object in the VM.
|
||||
type Object interface {
|
||||
// TypeName should return the name of the type.
|
||||
TypeName() string
|
||||
|
||||
// String should return a string representation of the type's value.
|
||||
String() string
|
||||
|
||||
// BinaryOp should return another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
// If BinaryOp returns an error, the VM will treat it as a run-time error.
|
||||
BinaryOp(op token.Token, rhs Object) (Object, error)
|
||||
|
||||
// IsFalsy should return true if the value of the type
|
||||
// should be considered as falsy.
|
||||
IsFalsy() bool
|
||||
|
||||
// Equals should return true if the value of the type
|
||||
// should be considered as equal to the value of another object.
|
||||
Equals(another Object) bool
|
||||
|
||||
// Copy should return a copy of the type (and its value).
|
||||
// Copy function will be used for copy() builtin function
|
||||
// which is expected to deep-copy the values generally.
|
||||
Copy() Object
|
||||
}
|
12
vendor/github.com/d5/tengo/objects/objects.go
generated
vendored
Normal file
12
vendor/github.com/d5/tengo/objects/objects.go
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
package objects
|
||||
|
||||
var (
|
||||
// TrueValue represents a true value.
|
||||
TrueValue Object = &Bool{value: true}
|
||||
|
||||
// FalseValue represents a false value.
|
||||
FalseValue Object = &Bool{value: false}
|
||||
|
||||
// UndefinedValue represents an undefined value.
|
||||
UndefinedValue Object = &Undefined{}
|
||||
)
|
39
vendor/github.com/d5/tengo/objects/return_value.go
generated
vendored
Normal file
39
vendor/github.com/d5/tengo/objects/return_value.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
package objects
|
||||
|
||||
import "github.com/d5/tengo/compiler/token"
|
||||
|
||||
// ReturnValue represents a value that is being returned.
|
||||
type ReturnValue struct {
|
||||
Value Object
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *ReturnValue) TypeName() string {
|
||||
return "return-value"
|
||||
}
|
||||
|
||||
func (o *ReturnValue) String() string {
|
||||
return "<return-value>"
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *ReturnValue) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *ReturnValue) Copy() Object {
|
||||
return &ReturnValue{Value: o.Copy()}
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *ReturnValue) IsFalsy() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *ReturnValue) Equals(x Object) bool {
|
||||
return false
|
||||
}
|
95
vendor/github.com/d5/tengo/objects/string.go
generated
vendored
Normal file
95
vendor/github.com/d5/tengo/objects/string.go
generated
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// String represents a string value.
|
||||
type String struct {
|
||||
Value string
|
||||
runeStr []rune
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *String) TypeName() string {
|
||||
return "string"
|
||||
}
|
||||
|
||||
func (o *String) String() string {
|
||||
return strconv.Quote(o.Value)
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *String) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
switch op {
|
||||
case token.Add:
|
||||
switch rhs := rhs.(type) {
|
||||
case *String:
|
||||
return &String{Value: o.Value + rhs.Value}, nil
|
||||
default:
|
||||
return &String{Value: o.Value + rhs.String()}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *String) IsFalsy() bool {
|
||||
return len(o.Value) == 0
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *String) Copy() Object {
|
||||
return &String{Value: o.Value}
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *String) Equals(x Object) bool {
|
||||
t, ok := x.(*String)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return o.Value == t.Value
|
||||
}
|
||||
|
||||
// IndexGet returns a character at a given index.
|
||||
func (o *String) IndexGet(index Object) (res Object, err error) {
|
||||
intIdx, ok := index.(*Int)
|
||||
if !ok {
|
||||
err = ErrInvalidIndexType
|
||||
return
|
||||
}
|
||||
|
||||
idxVal := int(intIdx.Value)
|
||||
|
||||
if o.runeStr == nil {
|
||||
o.runeStr = []rune(o.Value)
|
||||
}
|
||||
|
||||
if idxVal < 0 || idxVal >= len(o.runeStr) {
|
||||
res = UndefinedValue
|
||||
return
|
||||
}
|
||||
|
||||
res = &Char{Value: o.runeStr[idxVal]}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Iterate creates a string iterator.
|
||||
func (o *String) Iterate() Iterator {
|
||||
if o.runeStr == nil {
|
||||
o.runeStr = []rune(o.Value)
|
||||
}
|
||||
|
||||
return &StringIterator{
|
||||
v: o.runeStr,
|
||||
l: len(o.runeStr),
|
||||
}
|
||||
}
|
57
vendor/github.com/d5/tengo/objects/string_iterator.go
generated
vendored
Normal file
57
vendor/github.com/d5/tengo/objects/string_iterator.go
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
package objects
|
||||
|
||||
import "github.com/d5/tengo/compiler/token"
|
||||
|
||||
// StringIterator represents an iterator for a string.
|
||||
type StringIterator struct {
|
||||
v []rune
|
||||
i int
|
||||
l int
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (i *StringIterator) TypeName() string {
|
||||
return "string-iterator"
|
||||
}
|
||||
|
||||
func (i *StringIterator) String() string {
|
||||
return "<string-iterator>"
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (i *StringIterator) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (i *StringIterator) IsFalsy() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (i *StringIterator) Equals(Object) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (i *StringIterator) Copy() Object {
|
||||
return &StringIterator{v: i.v, i: i.i, l: i.l}
|
||||
}
|
||||
|
||||
// Next returns true if there are more elements to iterate.
|
||||
func (i *StringIterator) Next() bool {
|
||||
i.i++
|
||||
return i.i <= i.l
|
||||
}
|
||||
|
||||
// Key returns the key or index value of the current element.
|
||||
func (i *StringIterator) Key() Object {
|
||||
return &Int{Value: int64(i.i - 1)}
|
||||
}
|
||||
|
||||
// Value returns the value of the current element.
|
||||
func (i *StringIterator) Value() Object {
|
||||
return &Char{Value: i.v[i.i-1]}
|
||||
}
|
89
vendor/github.com/d5/tengo/objects/time.go
generated
vendored
Normal file
89
vendor/github.com/d5/tengo/objects/time.go
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// Time represents a time value.
|
||||
type Time struct {
|
||||
Value time.Time
|
||||
}
|
||||
|
||||
func (o *Time) String() string {
|
||||
return o.Value.String()
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *Time) TypeName() string {
|
||||
return "time"
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *Time) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
switch rhs := rhs.(type) {
|
||||
case *Int:
|
||||
switch op {
|
||||
case token.Add: // time + int => time
|
||||
if rhs.Value == 0 {
|
||||
return o, nil
|
||||
}
|
||||
return &Time{Value: o.Value.Add(time.Duration(rhs.Value))}, nil
|
||||
case token.Sub: // time - int => time
|
||||
if rhs.Value == 0 {
|
||||
return o, nil
|
||||
}
|
||||
return &Time{Value: o.Value.Add(time.Duration(-rhs.Value))}, nil
|
||||
}
|
||||
case *Time:
|
||||
switch op {
|
||||
case token.Sub: // time - time => int (duration)
|
||||
return &Int{Value: int64(o.Value.Sub(rhs.Value))}, nil
|
||||
case token.Less: // time < time => bool
|
||||
if o.Value.Before(rhs.Value) {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.Greater:
|
||||
if o.Value.After(rhs.Value) {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.LessEq:
|
||||
if o.Value.Equal(rhs.Value) || o.Value.Before(rhs.Value) {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
case token.GreaterEq:
|
||||
if o.Value.Equal(rhs.Value) || o.Value.After(rhs.Value) {
|
||||
return TrueValue, nil
|
||||
}
|
||||
return FalseValue, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *Time) Copy() Object {
|
||||
return &Time{Value: o.Value}
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *Time) IsFalsy() bool {
|
||||
return o.Value.IsZero()
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *Time) Equals(x Object) bool {
|
||||
t, ok := x.(*Time)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return o.Value.Equal(t.Value)
|
||||
}
|
42
vendor/github.com/d5/tengo/objects/undefined.go
generated
vendored
Normal file
42
vendor/github.com/d5/tengo/objects/undefined.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
package objects
|
||||
|
||||
import "github.com/d5/tengo/compiler/token"
|
||||
|
||||
// Undefined represents an undefined value.
|
||||
type Undefined struct{}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *Undefined) TypeName() string {
|
||||
return "undefined"
|
||||
}
|
||||
|
||||
func (o *Undefined) String() string {
|
||||
return "<undefined>"
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *Undefined) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *Undefined) Copy() Object {
|
||||
return o
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *Undefined) IsFalsy() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *Undefined) Equals(x Object) bool {
|
||||
return o == x
|
||||
}
|
||||
|
||||
// IndexGet returns an element at a given index.
|
||||
func (o *Undefined) IndexGet(index Object) (Object, error) {
|
||||
return UndefinedValue, nil
|
||||
}
|
47
vendor/github.com/d5/tengo/objects/user_function.go
generated
vendored
Normal file
47
vendor/github.com/d5/tengo/objects/user_function.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
package objects
|
||||
|
||||
import (
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
)
|
||||
|
||||
// UserFunction represents a user function.
|
||||
type UserFunction struct {
|
||||
Name string
|
||||
Value CallableFunc
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
func (o *UserFunction) TypeName() string {
|
||||
return "user-function:" + o.Name
|
||||
}
|
||||
|
||||
func (o *UserFunction) String() string {
|
||||
return "<user-function>"
|
||||
}
|
||||
|
||||
// BinaryOp returns another object that is the result of
|
||||
// a given binary operator and a right-hand side object.
|
||||
func (o *UserFunction) BinaryOp(op token.Token, rhs Object) (Object, error) {
|
||||
return nil, ErrInvalidOperator
|
||||
}
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *UserFunction) Copy() Object {
|
||||
return &UserFunction{Value: o.Value}
|
||||
}
|
||||
|
||||
// IsFalsy returns true if the value of the type is falsy.
|
||||
func (o *UserFunction) IsFalsy() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type
|
||||
// is equal to the value of another object.
|
||||
func (o *UserFunction) Equals(x Object) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Call invokes a user function.
|
||||
func (o *UserFunction) Call(args ...Object) (Object, error) {
|
||||
return o.Value(args...)
|
||||
}
|
Reference in New Issue
Block a user