From e302d643a176c0208ace8e41d969220032e273da Mon Sep 17 00:00:00 2001 From: E Sequeira Date: Wed, 20 Jul 2022 10:08:24 +0100 Subject: [PATCH 1/3] faster BinaryOp --- builtins.go | 49 ++-- builtins_test.go | 176 ++++++------ bytecode.go | 15 +- bytecode_test.go | 104 +++---- cmd/bench/main.go | 12 +- compiler.go | 6 +- compiler_test.go | 4 +- docs/objects.md | 23 +- examples/interoperability/main.go | 12 +- formatter.go | 4 +- iterator.go | 18 +- objects.go | 261 ++++++++++------- objects_test.go | 454 +++++++++++++++--------------- require/require.go | 12 +- script_test.go | 14 +- stdlib/func_typedefs.go | 30 +- stdlib/func_typedefs_test.go | 86 +++--- stdlib/json/decode.go | 2 +- stdlib/json/encode.go | 6 +- stdlib/math.go | 22 +- stdlib/os.go | 58 ++-- stdlib/os_file.go | 2 +- stdlib/os_test.go | 8 +- stdlib/rand.go | 4 +- stdlib/stdlib_test.go | 12 +- stdlib/text.go | 16 +- stdlib/text_regexp.go | 8 +- stdlib/times.go | 72 ++--- stdlib/times_test.go | 4 +- tengo.go | 38 +-- tengo_test.go | 48 ++-- variable_test.go | 2 +- vm.go | 27 +- vm_test.go | 51 ++-- 34 files changed, 861 insertions(+), 799 deletions(-) diff --git a/builtins.go b/builtins.go index b954d072..8812671c 100644 --- a/builtins.go +++ b/builtins.go @@ -153,7 +153,7 @@ func builtinIsInt(args ...Object) (Object, error) { if len(args) != 1 { return nil, ErrWrongNumArguments } - if _, ok := args[0].(*Int); ok { + if _, ok := args[0].(Int); ok { return TrueValue, nil } return FalseValue, nil @@ -163,7 +163,7 @@ func builtinIsFloat(args ...Object) (Object, error) { if len(args) != 1 { return nil, ErrWrongNumArguments } - if _, ok := args[0].(*Float); ok { + if _, ok := args[0].(Float); ok { return TrueValue, nil } return FalseValue, nil @@ -183,7 +183,7 @@ func builtinIsChar(args ...Object) (Object, error) { if len(args) != 1 { return nil, ErrWrongNumArguments } - if _, ok := args[0].(*Char); ok { + if _, ok := args[0].(Char); ok { return TrueValue, nil } return FalseValue, nil @@ -307,17 +307,17 @@ func builtinLen(args ...Object) (Object, error) { } switch arg := args[0].(type) { case *Array: - return &Int{Value: int64(len(arg.Value))}, nil + return Int{Value: int64(len(arg.Value))}, nil case *ImmutableArray: - return &Int{Value: int64(len(arg.Value))}, nil + return Int{Value: int64(len(arg.Value))}, nil case *String: - return &Int{Value: int64(len(arg.Value))}, nil + return Int{Value: int64(len(arg.Value))}, nil case *Bytes: - return &Int{Value: int64(len(arg.Value))}, nil + return Int{Value: int64(len(arg.Value))}, nil case *Map: - return &Int{Value: int64(len(arg.Value))}, nil + return Int{Value: int64(len(arg.Value))}, nil case *ImmutableMap: - return &Int{Value: int64(len(arg.Value))}, nil + return Int{Value: int64(len(arg.Value))}, nil default: return nil, ErrInvalidArgumentType{ Name: "first", @@ -333,10 +333,11 @@ func builtinRange(args ...Object) (Object, error) { if numArgs < 2 || numArgs > 3 { return nil, ErrWrongNumArguments } - var start, stop, step *Int + var start, stop Int + step := Int{Value: 1} for i, arg := range args { - v, ok := args[i].(*Int) + v, ok := args[i].(Int) if !ok { var name string switch i { @@ -367,10 +368,6 @@ func builtinRange(args ...Object) (Object, error) { } } - if step == nil { - step = &Int{Value: int64(1)} - } - return buildRange(start.Value, stop.Value, step.Value), nil } @@ -378,13 +375,13 @@ func buildRange(start, stop, step int64) *Array { array := &Array{} if start <= stop { for i := start; i < stop; i += step { - array.Value = append(array.Value, &Int{ + array.Value = append(array.Value, Int{ Value: i, }) } } else { for i := start; i > stop; i -= step { - array.Value = append(array.Value, &Int{ + array.Value = append(array.Value, Int{ Value: i, }) } @@ -449,12 +446,12 @@ func builtinInt(args ...Object) (Object, error) { if !(argsLen == 1 || argsLen == 2) { return nil, ErrWrongNumArguments } - if _, ok := args[0].(*Int); ok { + if _, ok := args[0].(Int); ok { return args[0], nil } v, ok := ToInt64(args[0]) if ok { - return &Int{Value: v}, nil + return Int{Value: v}, nil } if argsLen == 2 { return args[1], nil @@ -467,12 +464,12 @@ func builtinFloat(args ...Object) (Object, error) { if !(argsLen == 1 || argsLen == 2) { return nil, ErrWrongNumArguments } - if _, ok := args[0].(*Float); ok { + if _, ok := args[0].(Float); ok { return args[0], nil } v, ok := ToFloat64(args[0]) if ok { - return &Float{Value: v}, nil + return Float{Value: v}, nil } if argsLen == 2 { return args[1], nil @@ -502,12 +499,12 @@ func builtinChar(args ...Object) (Object, error) { if !(argsLen == 1 || argsLen == 2) { return nil, ErrWrongNumArguments } - if _, ok := args[0].(*Char); ok { + if _, ok := args[0].(Char); ok { return args[0], nil } v, ok := ToRune(args[0]) if ok { - return &Char{Value: v}, nil + return Char{Value: v}, nil } if argsLen == 2 { return args[1], nil @@ -522,7 +519,7 @@ func builtinBytes(args ...Object) (Object, error) { } // bytes(N) => create a new bytes with given size N - if n, ok := args[0].(*Int); ok { + if n, ok := args[0].(Int); ok { if n.Value > int64(MaxBytesLen) { return nil, ErrBytesLimit } @@ -627,7 +624,7 @@ func builtinSplice(args ...Object) (Object, error) { var startIdx int if argsLen > 1 { - arg1, ok := args[1].(*Int) + arg1, ok := args[1].(Int) if !ok { return nil, ErrInvalidArgumentType{ Name: "second", @@ -643,7 +640,7 @@ func builtinSplice(args ...Object) (Object, error) { delCount := len(array.Value) if argsLen > 2 { - arg2, ok := args[2].(*Int) + arg2, ok := args[2].(Int) if !ok { return nil, ErrInvalidArgumentType{ Name: "third", diff --git a/builtins_test.go b/builtins_test.go index eca2d5bb..28dd6a0d 100644 --- a/builtins_test.go +++ b/builtins_test.go @@ -52,7 +52,7 @@ func Test_builtinDelete(t *testing.T) { }, {name: "nil-map-nonstr-key", args: args{[]tengo.Object{ - &tengo.Map{}, &tengo.Int{}}}, wantErr: true, + &tengo.Map{}, tengo.Int{}}}, wantErr: true, wantedErr: tengo.ErrInvalidArgumentType{ Name: "second", Expected: "string", Found: "int"}, }, @@ -88,12 +88,12 @@ func Test_builtinDelete(t *testing.T) { []tengo.Object{ &tengo.Map{Value: map[string]tengo.Object{ "key1": &tengo.String{Value: "value1"}, - "key2": &tengo.Int{Value: 10}, + "key2": tengo.Int{Value: 10}, }}, &tengo.String{Value: "key1"}}}, want: tengo.UndefinedValue, target: &tengo.Map{Value: map[string]tengo.Object{ - "key2": &tengo.Int{Value: 10}}}, + "key2": tengo.Int{Value: 10}}}, }, } for _, tt := range tests { @@ -166,12 +166,12 @@ func Test_builtinSplice(t *testing.T) { Name: "second", Expected: "int", Found: "string"}, }, {name: "negative index", - args: []tengo.Object{&tengo.Array{}, &tengo.Int{Value: -1}}, + args: []tengo.Object{&tengo.Array{}, tengo.Int{Value: -1}}, wantErr: true, wantedErr: tengo.ErrIndexOutOfBounds}, {name: "non int count", args: []tengo.Object{ - &tengo.Array{}, &tengo.Int{Value: 0}, + &tengo.Array{}, tengo.Int{Value: 0}, &tengo.String{Value: ""}}, wantErr: true, wantedErr: tengo.ErrInvalidArgumentType{ @@ -180,153 +180,153 @@ func Test_builtinSplice(t *testing.T) { {name: "negative count", args: []tengo.Object{ &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 0}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}}}, - &tengo.Int{Value: 0}, - &tengo.Int{Value: -1}}, + tengo.Int{Value: 0}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}}}, + tengo.Int{Value: 0}, + tengo.Int{Value: -1}}, wantErr: true, wantedErr: tengo.ErrIndexOutOfBounds, }, {name: "insert with zero count", args: []tengo.Object{ &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 0}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}}}, - &tengo.Int{Value: 0}, - &tengo.Int{Value: 0}, + tengo.Int{Value: 0}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}}}, + tengo.Int{Value: 0}, + tengo.Int{Value: 0}, &tengo.String{Value: "b"}}, deleted: &tengo.Array{Value: []tengo.Object{}}, Array: &tengo.Array{Value: []tengo.Object{ &tengo.String{Value: "b"}, - &tengo.Int{Value: 0}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}}}, + tengo.Int{Value: 0}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}}}, }, {name: "insert", args: []tengo.Object{ &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 0}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}}}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 0}, + tengo.Int{Value: 0}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}}}, + tengo.Int{Value: 1}, + tengo.Int{Value: 0}, &tengo.String{Value: "c"}, &tengo.String{Value: "d"}}, deleted: &tengo.Array{Value: []tengo.Object{}}, Array: &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 0}, + tengo.Int{Value: 0}, &tengo.String{Value: "c"}, &tengo.String{Value: "d"}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}}}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}}}, }, {name: "insert with zero count", args: []tengo.Object{ &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 0}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}}}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 0}, + tengo.Int{Value: 0}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}}}, + tengo.Int{Value: 1}, + tengo.Int{Value: 0}, &tengo.String{Value: "c"}, &tengo.String{Value: "d"}}, deleted: &tengo.Array{Value: []tengo.Object{}}, Array: &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 0}, + tengo.Int{Value: 0}, &tengo.String{Value: "c"}, &tengo.String{Value: "d"}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}}}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}}}, }, {name: "insert with delete", args: []tengo.Object{ &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 0}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}}}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 1}, + tengo.Int{Value: 0}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}}}, + tengo.Int{Value: 1}, + tengo.Int{Value: 1}, &tengo.String{Value: "c"}, &tengo.String{Value: "d"}}, deleted: &tengo.Array{ - Value: []tengo.Object{&tengo.Int{Value: 1}}}, + Value: []tengo.Object{tengo.Int{Value: 1}}}, Array: &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 0}, + tengo.Int{Value: 0}, &tengo.String{Value: "c"}, &tengo.String{Value: "d"}, - &tengo.Int{Value: 2}}}, + tengo.Int{Value: 2}}}, }, {name: "insert with delete multi", args: []tengo.Object{ &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 0}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}}}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}, + tengo.Int{Value: 0}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}}}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}, &tengo.String{Value: "c"}, &tengo.String{Value: "d"}}, deleted: &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}}}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}}}, Array: &tengo.Array{ Value: []tengo.Object{ - &tengo.Int{Value: 0}, + tengo.Int{Value: 0}, &tengo.String{Value: "c"}, &tengo.String{Value: "d"}}}, }, {name: "delete all with positive count", args: []tengo.Object{ &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 0}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}}}, - &tengo.Int{Value: 0}, - &tengo.Int{Value: 3}}, + tengo.Int{Value: 0}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}}}, + tengo.Int{Value: 0}, + tengo.Int{Value: 3}}, deleted: &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 0}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}}}, + tengo.Int{Value: 0}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}}}, Array: &tengo.Array{Value: []tengo.Object{}}, }, {name: "delete all with big count", args: []tengo.Object{ &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 0}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}}}, - &tengo.Int{Value: 0}, - &tengo.Int{Value: 5}}, + tengo.Int{Value: 0}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}}}, + tengo.Int{Value: 0}, + tengo.Int{Value: 5}}, deleted: &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 0}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}}}, + tengo.Int{Value: 0}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}}}, Array: &tengo.Array{Value: []tengo.Object{}}, }, {name: "nothing2", args: []tengo.Object{ &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 0}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}}}}, + tengo.Int{Value: 0}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}}}}, Array: &tengo.Array{Value: []tengo.Object{}}, deleted: &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 0}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}}}, + tengo.Int{Value: 0}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}}}, }, {name: "pop without count", args: []tengo.Object{ &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 0}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}}}, - &tengo.Int{Value: 2}}, - deleted: &tengo.Array{Value: []tengo.Object{&tengo.Int{Value: 2}}}, + tengo.Int{Value: 0}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}}}, + tengo.Int{Value: 2}}, + deleted: &tengo.Array{Value: []tengo.Object{tengo.Int{Value: 2}}}, Array: &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 0}, &tengo.Int{Value: 1}}}, + tengo.Int{Value: 0}, tengo.Int{Value: 1}}}, }, } for _, tt := range tests { @@ -388,36 +388,36 @@ func Test_builtinRange(t *testing.T) { Name: "start", Expected: "int", Found: "string"}, }, {name: "invalid stop", - args: []tengo.Object{&tengo.Int{}, &tengo.String{}}, + args: []tengo.Object{tengo.Int{}, &tengo.String{}}, wantErr: true, wantedErr: tengo.ErrInvalidArgumentType{ Name: "stop", Expected: "int", Found: "string"}, }, {name: "invalid step", - args: []tengo.Object{&tengo.Int{}, &tengo.Int{}, &tengo.String{}}, + args: []tengo.Object{tengo.Int{}, tengo.Int{}, &tengo.String{}}, wantErr: true, wantedErr: tengo.ErrInvalidArgumentType{ Name: "step", Expected: "int", Found: "string"}, }, {name: "zero step", - args: []tengo.Object{&tengo.Int{}, &tengo.Int{}, &tengo.Int{}}, //must greate than 0 + args: []tengo.Object{tengo.Int{}, tengo.Int{}, tengo.Int{}}, //must greate than 0 wantErr: true, wantedErr: tengo.ErrInvalidRangeStep, }, {name: "negative step", - args: []tengo.Object{&tengo.Int{}, &tengo.Int{}, intObject(-2)}, //must greate than 0 + args: []tengo.Object{tengo.Int{}, tengo.Int{}, intObject(-2)}, //must greate than 0 wantErr: true, wantedErr: tengo.ErrInvalidRangeStep, }, {name: "same bound", - args: []tengo.Object{&tengo.Int{}, &tengo.Int{}}, + args: []tengo.Object{tengo.Int{}, tengo.Int{}}, wantErr: false, result: &tengo.Array{ Value: nil, }, }, {name: "positive range", - args: []tengo.Object{&tengo.Int{}, &tengo.Int{Value: 5}}, + args: []tengo.Object{tengo.Int{}, tengo.Int{Value: 5}}, wantErr: false, result: &tengo.Array{ Value: []tengo.Object{ @@ -430,7 +430,7 @@ func Test_builtinRange(t *testing.T) { }, }, {name: "negative range", - args: []tengo.Object{&tengo.Int{}, &tengo.Int{Value: -5}}, + args: []tengo.Object{tengo.Int{}, tengo.Int{Value: -5}}, wantErr: false, result: &tengo.Array{ Value: []tengo.Object{ @@ -444,7 +444,7 @@ func Test_builtinRange(t *testing.T) { }, {name: "positive with step", - args: []tengo.Object{&tengo.Int{}, &tengo.Int{Value: 5}, &tengo.Int{Value: 2}}, + args: []tengo.Object{tengo.Int{}, tengo.Int{Value: 5}, tengo.Int{Value: 2}}, wantErr: false, result: &tengo.Array{ Value: []tengo.Object{ @@ -456,7 +456,7 @@ func Test_builtinRange(t *testing.T) { }, {name: "negative with step", - args: []tengo.Object{&tengo.Int{}, &tengo.Int{Value: -10}, &tengo.Int{Value: 2}}, + args: []tengo.Object{tengo.Int{}, tengo.Int{Value: -10}, tengo.Int{Value: 2}}, wantErr: false, result: &tengo.Array{ Value: []tengo.Object{ @@ -470,7 +470,7 @@ func Test_builtinRange(t *testing.T) { }, {name: "large range", - args: []tengo.Object{intObject(-10), intObject(10), &tengo.Int{Value: 3}}, + args: []tengo.Object{intObject(-10), intObject(10), tengo.Int{Value: 3}}, wantErr: false, result: &tengo.Array{ Value: []tengo.Object{ diff --git a/bytecode.go b/bytecode.go index f3049cee..b63c9507 100644 --- a/bytecode.go +++ b/bytecode.go @@ -4,7 +4,6 @@ import ( "encoding/gob" "fmt" "io" - "reflect" "github.com/d5/tengo/v2/parser" ) @@ -56,7 +55,7 @@ func (b *Bytecode) FormatConstants() (output []string) { } default: output = append(output, fmt.Sprintf("[% 3d] %s (%s|%p)", - cidx, cn, reflect.TypeOf(cn).Elem().Name(), &cn)) + cidx, cn, cn.TypeName(), &cn)) } } return @@ -126,7 +125,7 @@ func (b *Bytecode) RemoveDuplicates() { indexMap[curIdx] = newIdx deduped = append(deduped, c) } - case *Int: + case Int: if newIdx, ok := ints[c.Value]; ok { indexMap[curIdx] = newIdx } else { @@ -144,7 +143,7 @@ func (b *Bytecode) RemoveDuplicates() { indexMap[curIdx] = newIdx deduped = append(deduped, c) } - case *Float: + case Float: if newIdx, ok := floats[c.Value]; ok { indexMap[curIdx] = newIdx } else { @@ -153,7 +152,7 @@ func (b *Bytecode) RemoveDuplicates() { indexMap[curIdx] = newIdx deduped = append(deduped, c) } - case *Char: + case Char: if newIdx, ok := chars[c.Value]; ok { indexMap[curIdx] = newIdx } else { @@ -283,13 +282,13 @@ func init() { gob.Register(&Array{}) gob.Register(&Bool{}) gob.Register(&Bytes{}) - gob.Register(&Char{}) + gob.Register(Char{}) gob.Register(&CompiledFunction{}) gob.Register(&Error{}) - gob.Register(&Float{}) + gob.Register(Float{}) gob.Register(&ImmutableArray{}) gob.Register(&ImmutableMap{}) - gob.Register(&Int{}) + gob.Register(Int{}) gob.Register(&Map{}) gob.Register(&String{}) gob.Register(&Time{}) diff --git a/bytecode_test.go b/bytecode_test.go index 7d1a5001..083eb32c 100644 --- a/bytecode_test.go +++ b/bytecode_test.go @@ -20,15 +20,15 @@ func TestBytecode(t *testing.T) { testBytecodeSerialization(t, bytecode( concatInsts(), objectsArray( - &tengo.Char{Value: 'y'}, - &tengo.Float{Value: 93.11}, + tengo.Char{Value: 'y'}, + tengo.Float{Value: 93.11}, compiledFunction(1, 0, tengo.MakeInstruction(parser.OpConstant, 3), tengo.MakeInstruction(parser.OpSetLocal, 0), tengo.MakeInstruction(parser.OpGetGlobal, 0), tengo.MakeInstruction(parser.OpGetFree, 0)), - &tengo.Float{Value: 39.2}, - &tengo.Int{Value: 192}, + tengo.Float{Value: 39.2}, + tengo.Int{Value: 192}, &tengo.String{Value: "bar"}))) testBytecodeSerialization(t, bytecodeFileSet( @@ -38,17 +38,17 @@ func TestBytecode(t *testing.T) { tengo.MakeInstruction(parser.OpConstant, 6), tengo.MakeInstruction(parser.OpPop)), objectsArray( - &tengo.Int{Value: 55}, - &tengo.Int{Value: 66}, - &tengo.Int{Value: 77}, - &tengo.Int{Value: 88}, + tengo.Int{Value: 55}, + tengo.Int{Value: 66}, + tengo.Int{Value: 77}, + tengo.Int{Value: 88}, &tengo.ImmutableMap{ Value: map[string]tengo.Object{ "array": &tengo.ImmutableArray{ Value: []tengo.Object{ - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}, - &tengo.Int{Value: 3}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}, + tengo.Int{Value: 3}, tengo.TrueValue, tengo.FalseValue, tengo.UndefinedValue, @@ -57,16 +57,16 @@ func TestBytecode(t *testing.T) { "true": tengo.TrueValue, "false": tengo.FalseValue, "bytes": &tengo.Bytes{Value: make([]byte, 16)}, - "char": &tengo.Char{Value: 'Y'}, + "char": tengo.Char{Value: 'Y'}, "error": &tengo.Error{Value: &tengo.String{ Value: "some error", }}, - "float": &tengo.Float{Value: -19.84}, + "float": tengo.Float{Value: -19.84}, "immutable_array": &tengo.ImmutableArray{ Value: []tengo.Object{ - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}, - &tengo.Int{Value: 3}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}, + tengo.Int{Value: 3}, tengo.TrueValue, tengo.FalseValue, tengo.UndefinedValue, @@ -74,20 +74,20 @@ func TestBytecode(t *testing.T) { }, "immutable_map": &tengo.ImmutableMap{ Value: map[string]tengo.Object{ - "a": &tengo.Int{Value: 1}, - "b": &tengo.Int{Value: 2}, - "c": &tengo.Int{Value: 3}, + "a": tengo.Int{Value: 1}, + "b": tengo.Int{Value: 2}, + "c": tengo.Int{Value: 3}, "d": tengo.TrueValue, "e": tengo.FalseValue, "f": tengo.UndefinedValue, }, }, - "int": &tengo.Int{Value: 91}, + "int": tengo.Int{Value: 91}, "map": &tengo.Map{ Value: map[string]tengo.Object{ - "a": &tengo.Int{Value: 1}, - "b": &tengo.Int{Value: 2}, - "c": &tengo.Int{Value: 3}, + "a": tengo.Int{Value: 1}, + "b": tengo.Int{Value: 2}, + "c": tengo.Int{Value: 3}, "d": tengo.TrueValue, "e": tengo.FalseValue, "f": tengo.UndefinedValue, @@ -130,27 +130,27 @@ func TestBytecode_RemoveDuplicates(t *testing.T) { testBytecodeRemoveDuplicates(t, bytecode( concatInsts(), objectsArray( - &tengo.Char{Value: 'y'}, - &tengo.Float{Value: 93.11}, + tengo.Char{Value: 'y'}, + tengo.Float{Value: 93.11}, compiledFunction(1, 0, tengo.MakeInstruction(parser.OpConstant, 3), tengo.MakeInstruction(parser.OpSetLocal, 0), tengo.MakeInstruction(parser.OpGetGlobal, 0), tengo.MakeInstruction(parser.OpGetFree, 0)), - &tengo.Float{Value: 39.2}, - &tengo.Int{Value: 192}, + tengo.Float{Value: 39.2}, + tengo.Int{Value: 192}, &tengo.String{Value: "bar"})), bytecode( concatInsts(), objectsArray( - &tengo.Char{Value: 'y'}, - &tengo.Float{Value: 93.11}, + tengo.Char{Value: 'y'}, + tengo.Float{Value: 93.11}, compiledFunction(1, 0, tengo.MakeInstruction(parser.OpConstant, 3), tengo.MakeInstruction(parser.OpSetLocal, 0), tengo.MakeInstruction(parser.OpGetGlobal, 0), tengo.MakeInstruction(parser.OpGetFree, 0)), - &tengo.Float{Value: 39.2}, - &tengo.Int{Value: 192}, + tengo.Float{Value: 39.2}, + tengo.Int{Value: 192}, &tengo.String{Value: "bar"}))) testBytecodeRemoveDuplicates(t, @@ -167,9 +167,9 @@ func TestBytecode_RemoveDuplicates(t *testing.T) { tengo.MakeInstruction(parser.OpConstant, 8), tengo.MakeInstruction(parser.OpClosure, 4, 1)), objectsArray( - &tengo.Int{Value: 1}, - &tengo.Float{Value: 2.0}, - &tengo.Char{Value: '3'}, + tengo.Int{Value: 1}, + tengo.Float{Value: 2.0}, + tengo.Char{Value: '3'}, &tengo.String{Value: "four"}, compiledFunction(1, 0, tengo.MakeInstruction(parser.OpConstant, 3), @@ -177,9 +177,9 @@ func TestBytecode_RemoveDuplicates(t *testing.T) { tengo.MakeInstruction(parser.OpSetLocal, 0), tengo.MakeInstruction(parser.OpGetGlobal, 0), tengo.MakeInstruction(parser.OpGetFree, 0)), - &tengo.Int{Value: 1}, - &tengo.Float{Value: 2.0}, - &tengo.Char{Value: '3'}, + tengo.Int{Value: 1}, + tengo.Float{Value: 2.0}, + tengo.Char{Value: '3'}, &tengo.String{Value: "four"})), bytecode( concatInsts( @@ -194,9 +194,9 @@ func TestBytecode_RemoveDuplicates(t *testing.T) { tengo.MakeInstruction(parser.OpConstant, 3), tengo.MakeInstruction(parser.OpClosure, 4, 1)), objectsArray( - &tengo.Int{Value: 1}, - &tengo.Float{Value: 2.0}, - &tengo.Char{Value: '3'}, + tengo.Int{Value: 1}, + tengo.Float{Value: 2.0}, + tengo.Char{Value: '3'}, &tengo.String{Value: "four"}, compiledFunction(1, 0, tengo.MakeInstruction(parser.OpConstant, 3), @@ -214,11 +214,11 @@ func TestBytecode_RemoveDuplicates(t *testing.T) { tengo.MakeInstruction(parser.OpConstant, 3), tengo.MakeInstruction(parser.OpConstant, 4)), objectsArray( - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}, - &tengo.Int{Value: 3}, - &tengo.Int{Value: 1}, - &tengo.Int{Value: 3})), + tengo.Int{Value: 1}, + tengo.Int{Value: 2}, + tengo.Int{Value: 3}, + tengo.Int{Value: 1}, + tengo.Int{Value: 3})), bytecode( concatInsts( tengo.MakeInstruction(parser.OpConstant, 0), @@ -227,19 +227,19 @@ func TestBytecode_RemoveDuplicates(t *testing.T) { tengo.MakeInstruction(parser.OpConstant, 0), tengo.MakeInstruction(parser.OpConstant, 2)), objectsArray( - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}, - &tengo.Int{Value: 3}))) + tengo.Int{Value: 1}, + tengo.Int{Value: 2}, + tengo.Int{Value: 3}))) } func TestBytecode_CountObjects(t *testing.T) { b := bytecode( concatInsts(), objectsArray( - &tengo.Int{Value: 55}, - &tengo.Int{Value: 66}, - &tengo.Int{Value: 77}, - &tengo.Int{Value: 88}, + tengo.Int{Value: 55}, + tengo.Int{Value: 66}, + tengo.Int{Value: 77}, + tengo.Int{Value: 88}, compiledFunction(1, 0, tengo.MakeInstruction(parser.OpConstant, 3), tengo.MakeInstruction(parser.OpReturn, 1)), diff --git a/cmd/bench/main.go b/cmd/bench/main.go index 0371d87c..91691773 100644 --- a/cmd/bench/main.go +++ b/cmd/bench/main.go @@ -36,9 +36,9 @@ fib := func(x) { panic(err) } - if nativeResult != int(result.(*tengo.Int).Value) { + if nativeResult != int(result.(tengo.Int).Value) { panic(fmt.Errorf("wrong result: %d != %d", nativeResult, - int(result.(*tengo.Int).Value))) + int(result.(tengo.Int).Value))) } fmt.Println("-------------------------------------") @@ -73,9 +73,9 @@ fib := func(x, s) { panic(err) } - if nativeResult != int(result.(*tengo.Int).Value) { + if nativeResult != int(result.(tengo.Int).Value) { panic(fmt.Errorf("wrong result: %d != %d", nativeResult, - int(result.(*tengo.Int).Value))) + int(result.(tengo.Int).Value))) } fmt.Println("-------------------------------------") @@ -110,9 +110,9 @@ fib := func(x, a, b) { panic(err) } - if nativeResult != int(result.(*tengo.Int).Value) { + if nativeResult != int(result.(tengo.Int).Value) { panic(fmt.Errorf("wrong result: %d != %d", nativeResult, - int(result.(*tengo.Int).Value))) + int(result.(tengo.Int).Value))) } fmt.Println("-------------------------------------") diff --git a/compiler.go b/compiler.go index 6591603c..d2f080e9 100644 --- a/compiler.go +++ b/compiler.go @@ -204,10 +204,10 @@ func (c *Compiler) Compile(node parser.Node) error { } case *parser.IntLit: c.emit(node, parser.OpConstant, - c.addConstant(&Int{Value: node.Value})) + c.addConstant(Int{Value: node.Value})) case *parser.FloatLit: c.emit(node, parser.OpConstant, - c.addConstant(&Float{Value: node.Value})) + c.addConstant(Float{Value: node.Value})) case *parser.BoolLit: if node.Value { c.emit(node, parser.OpTrue) @@ -222,7 +222,7 @@ func (c *Compiler) Compile(node parser.Node) error { c.addConstant(&String{Value: node.Value})) case *parser.CharLit: c.emit(node, parser.OpConstant, - c.addConstant(&Char{Value: node.Value})) + c.addConstant(Char{Value: node.Value})) case *parser.UndefinedLit: c.emit(node, parser.OpNull) case *parser.UnaryExpr: diff --git a/compiler_test.go b/compiler_test.go index fd1d422f..efda74d5 100644 --- a/compiler_test.go +++ b/compiler_test.go @@ -1458,8 +1458,8 @@ func objectsArray(o ...tengo.Object) []tengo.Object { return o } -func intObject(v int64) *tengo.Int { - return &tengo.Int{Value: v} +func intObject(v int64) tengo.Int { + return tengo.Int{Value: v} } func stringObject(v string) *tengo.String { diff --git a/docs/objects.md b/docs/objects.md index 4b150601..3bdf4811 100644 --- a/docs/objects.md +++ b/docs/objects.md @@ -227,14 +227,14 @@ for more details on these runtime types. Users can easily extend and add their own types by implementing the same [Object](https://godoc.org/github.com/d5/tengo#Object) interface and the -default `ObjectImpl` implementation. Tengo runtime will treat them in the +default `PtrObjectImpl` or `ObjectImpl` implementation. Tengo runtime will treat them in the same way as its runtime types with no performance overhead. Here's an example user type implementation, `StringArray`: ```golang type StringArray struct { - tengo.ObjectImpl + tengo.PtrObjectImpl Value []string } @@ -309,7 +309,7 @@ It can also implement `IndexGet` and `IndexSet`: ```golang func (o *StringArray) IndexGet(index tengo.Object) (tengo.Object, error) { - intIdx, ok := index.(*tengo.Int) + intIdx, ok := index.(tengo.Int) if ok { if intIdx.Value >= 0 && intIdx.Value < int64(len(o.Value)) { return &tengo.String{Value: o.Value[intIdx.Value]}, nil @@ -322,7 +322,7 @@ func (o *StringArray) IndexGet(index tengo.Object) (tengo.Object, error) { if ok { for vidx, str := range o.Value { if strIdx.Value == str { - return &tengo.Int{Value: int64(vidx)}, nil + return tengo.Int{Value: int64(vidx)}, nil } } @@ -338,7 +338,7 @@ func (o *StringArray) IndexSet(index, value tengo.Object) error { return tengo.ErrInvalidIndexValueType } - intIdx, ok := index.(*tengo.Int) + intIdx, ok := index.(tengo.Int) if ok { if intIdx.Value >= 0 && intIdx.Value < int64(len(o.Value)) { o.Value[intIdx.Value] = strVal @@ -375,7 +375,7 @@ func (o *StringArray) Call(args ...tengo.Object) (ret tengo.Object, err error) { for i, v := range o.Value { if v == s1 { - return &tengo.Int{Value: int64(i)}, nil + return tengo.Int{Value: int64(i)}, nil } } @@ -409,7 +409,7 @@ func (o *StringArray) Iterate() tengo.Iterator { } type StringArrayIterator struct { - tengo.ObjectImpl + tengo.PtrObjectImpl strArr *StringArray idx int } @@ -424,17 +424,16 @@ func (i *StringArrayIterator) Next() bool { } func (i *StringArrayIterator) Key() tengo.Object { - return &tengo.Int{Value: int64(i.idx - 1)} + return tengo.Int{Value: int64(i.idx - 1)} } func (i *StringArrayIterator) Value() tengo.Object { return &tengo.String{Value: i.strArr.Value[i.idx-1]} } ``` +### PtrObjectImpl and ObjectImpl -### ObjectImpl - -ObjectImpl represents a default Object Implementation. To defined a new value -type, one can embed ObjectImpl in their type declarations to avoid implementing +PtrObjectImpl and ObjectImpl represent a default Object Implementation. To defined a new value +type, one can embed PtrObjectImpl or ObjectImpl in their type declarations to avoid implementing all non-significant methods. TypeName() and String() methods still need to be implemented. diff --git a/examples/interoperability/main.go b/examples/interoperability/main.go index b62e2bff..78bf33f1 100644 --- a/examples/interoperability/main.go +++ b/examples/interoperability/main.go @@ -39,7 +39,7 @@ func NewGoProxy(ctx context.Context) *GoProxy { // GoProxy is a builtin tengo module to register tengo functions and run them. type GoProxy struct { - tengo.ObjectImpl + tengo.PtrObjectImpl ctx context.Context moduleMap map[string]tengo.Object callbacks map[string]tengo.Object @@ -145,7 +145,7 @@ func (mod *GoProxy) args(args ...tengo.Object) (tengo.Object, error) { } return tengo.UndefinedValue, nil }}, - "num_params": &tengo.Int{Value: int64(compiledFunc.NumParameters)}, + "num_params": tengo.Int{Value: int64(compiledFunc.NumParameters)}, "callable": compiledFunc, "params": &tengo.Array{Value: params}, }, @@ -243,8 +243,8 @@ func main() { fmt.Println("Calling tengo sum function") i1, i2 := rand.Int63n(100), rand.Int63n(100) callChan <- &CallArgs{Func: "sum", - Params: []tengo.Object{&tengo.Int{Value: i1}, - &tengo.Int{Value: i2}}, + Params: []tengo.Object{tengo.Int{Value: i1}, + tengo.Int{Value: i2}}, Result: result, } v := <-result @@ -253,8 +253,8 @@ func main() { fmt.Println("Calling tengo multiply function") i1, i2 = rand.Int63n(20), rand.Int63n(20) callChan <- &CallArgs{Func: "multiply", - Params: []tengo.Object{&tengo.Int{Value: i1}, - &tengo.Int{Value: i2}}, + Params: []tengo.Object{tengo.Int{Value: i1}, + tengo.Int{Value: i2}}, Result: result, } v = <-result diff --git a/formatter.go b/formatter.go index 0dbf71c6..3ec63546 100644 --- a/formatter.go +++ b/formatter.go @@ -953,9 +953,9 @@ func (p *pp) printArg(arg Object, verb rune) { switch f := arg.(type) { case *Bool: p.fmtBool(!f.IsFalsy(), verb) - case *Float: + case Float: p.fmtFloat(f.Value, 64, verb) - case *Int: + case Int: p.fmtInteger(uint64(f.Value), signed, verb) case *String: p.fmtString(f.Value, verb) diff --git a/iterator.go b/iterator.go index 13adbbab..46a4816d 100644 --- a/iterator.go +++ b/iterator.go @@ -16,7 +16,7 @@ type Iterator interface { // ArrayIterator is an iterator for an array. type ArrayIterator struct { - ObjectImpl + PtrObjectImpl v []Object i int l int @@ -55,7 +55,7 @@ func (i *ArrayIterator) Next() bool { // Key returns the key or index value of the current element. func (i *ArrayIterator) Key() Object { - return &Int{Value: int64(i.i - 1)} + return Int{Value: int64(i.i - 1)} } // Value returns the value of the current element. @@ -65,7 +65,7 @@ func (i *ArrayIterator) Value() Object { // BytesIterator represents an iterator for a string. type BytesIterator struct { - ObjectImpl + PtrObjectImpl v []byte i int l int @@ -99,17 +99,17 @@ func (i *BytesIterator) Next() bool { // Key returns the key or index value of the current element. func (i *BytesIterator) Key() Object { - return &Int{Value: int64(i.i - 1)} + return Int{Value: int64(i.i - 1)} } // Value returns the value of the current element. func (i *BytesIterator) Value() Object { - return &Int{Value: int64(i.v[i.i-1])} + return Int{Value: int64(i.v[i.i-1])} } // MapIterator represents an iterator for the map. type MapIterator struct { - ObjectImpl + PtrObjectImpl v map[string]Object k []string i int @@ -161,7 +161,7 @@ func (i *MapIterator) Value() Object { // StringIterator represents an iterator for a string. type StringIterator struct { - ObjectImpl + PtrObjectImpl v []rune i int l int @@ -200,10 +200,10 @@ func (i *StringIterator) Next() bool { // Key returns the key or index value of the current element. func (i *StringIterator) Key() Object { - return &Int{Value: int64(i.i - 1)} + 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]} + return Char{Value: i.v[i.i-1]} } diff --git a/objects.go b/objects.go index 25745586..4a2a0e9d 100644 --- a/objects.go +++ b/objects.go @@ -79,78 +79,147 @@ type Object interface { CanCall() bool } -// ObjectImpl represents a default Object Implementation. To defined a new -// value type, one can embed ObjectImpl in their type declarations to avoid +// PtrObjectImpl represents a default Object Implementation. To defined a new +// value type, one can embed PtrObjectImpl in their type declarations to avoid // implementing all non-significant methods. TypeName() and String() methods // still need to be implemented. type ObjectImpl struct { } // TypeName returns the name of the type. -func (o *ObjectImpl) TypeName() string { +func (o ObjectImpl) TypeName() string { panic(ErrNotImplemented) } -func (o *ObjectImpl) String() string { +func (o ObjectImpl) String() string { panic(ErrNotImplemented) } // BinaryOp returns another object that is the result of a given binary // operator and a right-hand side object. -func (o *ObjectImpl) BinaryOp(_ token.Token, _ Object) (Object, error) { +func (o ObjectImpl) BinaryOp(_ token.Token, _ Object) (Object, error) { return nil, ErrInvalidOperator } // Copy returns a copy of the type. -func (o *ObjectImpl) Copy() Object { +func (o ObjectImpl) Copy() Object { return nil } // IsFalsy returns true if the value of the type is falsy. -func (o *ObjectImpl) IsFalsy() bool { +func (o ObjectImpl) IsFalsy() bool { return false } // Equals returns true if the value of the type is equal to the value of // another object. -func (o *ObjectImpl) Equals(x Object) bool { +func (o ObjectImpl) Equals(x Object) bool { return o == x } // IndexGet returns an element at a given index. -func (o *ObjectImpl) IndexGet(_ Object) (res Object, err error) { +func (o ObjectImpl) IndexGet(_ Object) (res Object, err error) { return nil, ErrNotIndexable } // IndexSet sets an element at a given index. -func (o *ObjectImpl) IndexSet(_, _ Object) (err error) { +func (o ObjectImpl) IndexSet(_, _ Object) (err error) { return ErrNotIndexAssignable } // Iterate returns an iterator. -func (o *ObjectImpl) Iterate() Iterator { +func (o ObjectImpl) Iterate() Iterator { return nil } // CanIterate returns whether the Object can be Iterated. -func (o *ObjectImpl) CanIterate() bool { +func (o ObjectImpl) CanIterate() bool { return false } // Call takes an arbitrary number of arguments and returns a return value // and/or an error. -func (o *ObjectImpl) Call(_ ...Object) (ret Object, err error) { +func (o ObjectImpl) Call(_ ...Object) (ret Object, err error) { return nil, nil } // CanCall returns whether the Object can be Called. -func (o *ObjectImpl) CanCall() bool { +func (o ObjectImpl) CanCall() bool { + return false +} + +// PtrObjectImpl represents a default Object Implementation. To defined a new +// value type, one can embed PtrObjectImpl in their type declarations to avoid +// implementing all non-significant methods. TypeName() and String() methods +// still need to be implemented. +type PtrObjectImpl struct { +} + +// TypeName returns the name of the type. +func (o *PtrObjectImpl) TypeName() string { + panic(ErrNotImplemented) +} + +func (o *PtrObjectImpl) String() string { + panic(ErrNotImplemented) +} + +// BinaryOp returns another object that is the result of a given binary +// operator and a right-hand side object. +func (o *PtrObjectImpl) BinaryOp(_ token.Token, _ Object) (Object, error) { + return nil, ErrInvalidOperator +} + +// Copy returns a copy of the type. +func (o *PtrObjectImpl) Copy() Object { + return nil +} + +// IsFalsy returns true if the value of the type is falsy. +func (o *PtrObjectImpl) IsFalsy() bool { + return false +} + +// Equals returns true if the value of the type is equal to the value of +// another object. +func (o *PtrObjectImpl) Equals(x Object) bool { + return o == x +} + +// IndexGet returns an element at a given index. +func (o *PtrObjectImpl) IndexGet(_ Object) (res Object, err error) { + return nil, ErrNotIndexable +} + +// IndexSet sets an element at a given index. +func (o *PtrObjectImpl) IndexSet(_, _ Object) (err error) { + return ErrNotIndexAssignable +} + +// Iterate returns an iterator. +func (o *PtrObjectImpl) Iterate() Iterator { + return nil +} + +// CanIterate returns whether the Object can be Iterated. +func (o *PtrObjectImpl) CanIterate() bool { + return false +} + +// Call takes an arbitrary number of arguments and returns a return value +// and/or an error. +func (o *PtrObjectImpl) Call(_ ...Object) (ret Object, err error) { + return nil, nil +} + +// CanCall returns whether the Object can be Called. +func (o *PtrObjectImpl) CanCall() bool { return false } // Array represents an array of objects. type Array struct { - ObjectImpl + PtrObjectImpl Value []Object } @@ -221,7 +290,7 @@ func (o *Array) Equals(x Object) bool { // IndexGet returns an element at a given index. func (o *Array) IndexGet(index Object) (res Object, err error) { - intIdx, ok := index.(*Int) + intIdx, ok := index.(Int) if !ok { err = ErrInvalidIndexType return @@ -265,7 +334,7 @@ func (o *Array) CanIterate() bool { // Bool represents a boolean value. type Bool struct { - ObjectImpl + PtrObjectImpl // this is intentionally non-public to force using objects.TrueValue and // FalseValue always @@ -319,7 +388,7 @@ func (o *Bool) GobEncode() (b []byte, err error) { // BuiltinFunction represents a builtin function. type BuiltinFunction struct { - ObjectImpl + PtrObjectImpl Name string Value CallableFunc } @@ -376,7 +445,7 @@ func (m *BuiltinModule) AsImmutableMap(moduleName string) *ImmutableMap { // Bytes represents a byte array. type Bytes struct { - ObjectImpl + PtrObjectImpl Value []byte } @@ -427,7 +496,7 @@ func (o *Bytes) Equals(x Object) bool { // IndexGet returns an element (as Int) at a given index. func (o *Bytes) IndexGet(index Object) (res Object, err error) { - intIdx, ok := index.(*Int) + intIdx, ok := index.(Int) if !ok { err = ErrInvalidIndexType return @@ -437,7 +506,7 @@ func (o *Bytes) IndexGet(index Object) (res Object, err error) { res = UndefinedValue return } - res = &Int{Value: int64(o.Value[idxVal])} + res = Int{Value: int64(o.Value[idxVal])} return } @@ -460,33 +529,33 @@ type Char struct { Value rune } -func (o *Char) String() string { +func (o Char) String() string { return string(o.Value) } // TypeName returns the name of the type. -func (o *Char) TypeName() string { +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) { +func (o Char) BinaryOp(op token.Token, rhs Object) (Object, error) { switch rhs := rhs.(type) { - case *Char: + case Char: switch op { case token.Add: r := o.Value + rhs.Value if r == o.Value { return o, nil } - return &Char{Value: r}, 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 + return Char{Value: r}, nil case token.Less: if o.Value < rhs.Value { return TrueValue, nil @@ -508,20 +577,20 @@ func (o *Char) BinaryOp(op token.Token, rhs Object) (Object, error) { } return FalseValue, nil } - case *Int: + 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 + 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 + return Char{Value: r}, nil case token.Less: if int64(o.Value) < rhs.Value { return TrueValue, nil @@ -548,19 +617,19 @@ func (o *Char) BinaryOp(op token.Token, rhs Object) (Object, error) { } // Copy returns a copy of the type. -func (o *Char) Copy() Object { - return &Char{Value: o.Value} +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 { +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) +func (o Char) Equals(x Object) bool { + t, ok := x.(Char) if !ok { return false } @@ -569,7 +638,7 @@ func (o *Char) Equals(x Object) bool { // CompiledFunction represents a compiled function. type CompiledFunction struct { - ObjectImpl + PtrObjectImpl Instructions []byte NumLocals int // number of local variables (including function parameters) NumParameters int @@ -622,7 +691,7 @@ func (o *CompiledFunction) CanCall() bool { // Error represents an error value. type Error struct { - ObjectImpl + PtrObjectImpl Value Object } @@ -670,45 +739,45 @@ type Float struct { Value float64 } -func (o *Float) String() string { +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 { +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) { +func (o Float) BinaryOp(op token.Token, rhs Object) (Object, error) { switch rhs := rhs.(type) { - case *Float: + case Float: switch op { case token.Add: r := o.Value + rhs.Value if r == o.Value { return o, nil } - return &Float{Value: r}, 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 + 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 + 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 + return Float{Value: r}, nil case token.Less: if o.Value < rhs.Value { return TrueValue, nil @@ -730,32 +799,32 @@ func (o *Float) BinaryOp(op token.Token, rhs Object) (Object, error) { } return FalseValue, nil } - case *Int: + 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 + 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 + 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 + 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 + return Float{Value: r}, nil case token.Less: if o.Value < float64(rhs.Value) { return TrueValue, nil @@ -782,19 +851,19 @@ func (o *Float) BinaryOp(op token.Token, rhs Object) (Object, error) { } // Copy returns a copy of the type. -func (o *Float) Copy() Object { - return &Float{Value: o.Value} +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 { +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) +func (o Float) Equals(x Object) bool { + t, ok := x.(Float) if !ok { return false } @@ -803,7 +872,7 @@ func (o *Float) Equals(x Object) bool { // ImmutableArray represents an immutable array of objects. type ImmutableArray struct { - ObjectImpl + PtrObjectImpl Value []Object } @@ -871,7 +940,7 @@ func (o *ImmutableArray) Equals(x Object) bool { // IndexGet returns an element at a given index. func (o *ImmutableArray) IndexGet(index Object) (res Object, err error) { - intIdx, ok := index.(*Int) + intIdx, ok := index.(Int) if !ok { err = ErrInvalidIndexType return @@ -900,7 +969,7 @@ func (o *ImmutableArray) CanIterate() bool { // ImmutableMap represents an immutable map object. type ImmutableMap struct { - ObjectImpl + PtrObjectImpl Value map[string]Object } @@ -993,87 +1062,87 @@ type Int struct { Value int64 } -func (o *Int) String() string { +func (o Int) String() string { return strconv.FormatInt(o.Value, 10) } // TypeName returns the name of the type. -func (o *Int) TypeName() string { +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) { +func (o Int) BinaryOp(op token.Token, rhs Object) (Object, error) { switch rhs := rhs.(type) { - case *Int: + case Int: switch op { case token.Add: r := o.Value + rhs.Value if r == o.Value { return o, nil } - return &Int{Value: r}, 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + return Int{Value: r}, nil case token.Less: if o.Value < rhs.Value { return TrueValue, nil @@ -1095,16 +1164,16 @@ func (o *Int) BinaryOp(op token.Token, rhs Object) (Object, error) { } return FalseValue, nil } - case *Float: + case Float: switch op { case token.Add: - return &Float{Value: float64(o.Value) + rhs.Value}, nil + return Float{Value: float64(o.Value) + rhs.Value}, nil case token.Sub: - return &Float{Value: float64(o.Value) - rhs.Value}, nil + return Float{Value: float64(o.Value) - rhs.Value}, nil case token.Mul: - return &Float{Value: float64(o.Value) * rhs.Value}, nil + return Float{Value: float64(o.Value) * rhs.Value}, nil case token.Quo: - return &Float{Value: float64(o.Value) / rhs.Value}, nil + return Float{Value: float64(o.Value) / rhs.Value}, nil case token.Less: if float64(o.Value) < rhs.Value { return TrueValue, nil @@ -1126,12 +1195,12 @@ func (o *Int) BinaryOp(op token.Token, rhs Object) (Object, error) { } return FalseValue, nil } - case *Char: + case Char: switch op { case token.Add: - return &Char{Value: rune(o.Value) + rhs.Value}, nil + return Char{Value: rune(o.Value) + rhs.Value}, nil case token.Sub: - return &Char{Value: rune(o.Value) - rhs.Value}, nil + return Char{Value: rune(o.Value) - rhs.Value}, nil case token.Less: if o.Value < int64(rhs.Value) { return TrueValue, nil @@ -1158,19 +1227,19 @@ func (o *Int) BinaryOp(op token.Token, rhs Object) (Object, error) { } // Copy returns a copy of the type. -func (o *Int) Copy() Object { - return &Int{Value: o.Value} +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 { +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) +func (o Int) Equals(x Object) bool { + t, ok := x.(Int) if !ok { return false } @@ -1179,7 +1248,7 @@ func (o *Int) Equals(x Object) bool { // Map represents a map of objects. type Map struct { - ObjectImpl + PtrObjectImpl Value map[string]Object } @@ -1279,7 +1348,7 @@ func (o *Map) CanIterate() bool { // ObjectPtr represents a free variable. type ObjectPtr struct { - ObjectImpl + PtrObjectImpl Value *Object } @@ -1310,7 +1379,7 @@ func (o *ObjectPtr) Equals(x Object) bool { // String represents a string value. type String struct { - ObjectImpl + PtrObjectImpl Value string runeStr []rune } @@ -1400,7 +1469,7 @@ func (o *String) Equals(x Object) bool { // IndexGet returns a character at a given index. func (o *String) IndexGet(index Object) (res Object, err error) { - intIdx, ok := index.(*Int) + intIdx, ok := index.(Int) if !ok { err = ErrInvalidIndexType return @@ -1413,7 +1482,7 @@ func (o *String) IndexGet(index Object) (res Object, err error) { res = UndefinedValue return } - res = &Char{Value: o.runeStr[idxVal]} + res = Char{Value: o.runeStr[idxVal]} return } @@ -1435,7 +1504,7 @@ func (o *String) CanIterate() bool { // Time represents a time value. type Time struct { - ObjectImpl + PtrObjectImpl Value time.Time } @@ -1452,7 +1521,7 @@ func (o *Time) TypeName() string { // operator and a right-hand side object. func (o *Time) BinaryOp(op token.Token, rhs Object) (Object, error) { switch rhs := rhs.(type) { - case *Int: + case Int: switch op { case token.Add: // time + int => time if rhs.Value == 0 { @@ -1468,7 +1537,7 @@ func (o *Time) BinaryOp(op token.Token, rhs Object) (Object, error) { case *Time: switch op { case token.Sub: // time - time => int (duration) - return &Int{Value: int64(o.Value.Sub(rhs.Value))}, nil + 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 @@ -1516,7 +1585,7 @@ func (o *Time) Equals(x Object) bool { // Undefined represents an undefined value. type Undefined struct { - ObjectImpl + PtrObjectImpl } // TypeName returns the name of the type. @@ -1576,7 +1645,7 @@ func (o *Undefined) Value() Object { // UserFunction represents a user function. type UserFunction struct { - ObjectImpl + PtrObjectImpl Name string Value CallableFunc } diff --git a/objects_test.go b/objects_test.go index 29a0b7d3..c7c3470a 100644 --- a/objects_test.go +++ b/objects_test.go @@ -9,11 +9,11 @@ import ( ) func TestObject_TypeName(t *testing.T) { - var o tengo.Object = &tengo.Int{} + var o tengo.Object = tengo.Int{} require.Equal(t, "int", o.TypeName()) - o = &tengo.Float{} + o = tengo.Float{} require.Equal(t, "float", o.TypeName()) - o = &tengo.Char{} + o = tengo.Char{} require.Equal(t, "char", o.TypeName()) o = &tengo.String{} require.Equal(t, "string", o.TypeName()) @@ -44,17 +44,17 @@ func TestObject_TypeName(t *testing.T) { } func TestObject_IsFalsy(t *testing.T) { - var o tengo.Object = &tengo.Int{Value: 0} + var o tengo.Object = tengo.Int{Value: 0} require.True(t, o.IsFalsy()) - o = &tengo.Int{Value: 1} + o = tengo.Int{Value: 1} require.False(t, o.IsFalsy()) - o = &tengo.Float{Value: 0} + o = tengo.Float{Value: 0} require.False(t, o.IsFalsy()) - o = &tengo.Float{Value: 1} + o = tengo.Float{Value: 1} require.False(t, o.IsFalsy()) - o = &tengo.Char{Value: ' '} + o = tengo.Char{Value: ' '} require.False(t, o.IsFalsy()) - o = &tengo.Char{Value: 'T'} + o = tengo.Char{Value: 'T'} require.False(t, o.IsFalsy()) o = &tengo.String{Value: ""} require.True(t, o.IsFalsy()) @@ -89,17 +89,17 @@ func TestObject_IsFalsy(t *testing.T) { } func TestObject_String(t *testing.T) { - var o tengo.Object = &tengo.Int{Value: 0} + var o tengo.Object = tengo.Int{Value: 0} require.Equal(t, "0", o.String()) - o = &tengo.Int{Value: 1} + o = tengo.Int{Value: 1} require.Equal(t, "1", o.String()) - o = &tengo.Float{Value: 0} + o = tengo.Float{Value: 0} require.Equal(t, "0", o.String()) - o = &tengo.Float{Value: 1} + o = tengo.Float{Value: 1} require.Equal(t, "1", o.String()) - o = &tengo.Char{Value: ' '} + o = tengo.Char{Value: ' '} require.Equal(t, " ", o.String()) - o = &tengo.Char{Value: 'T'} + o = tengo.Char{Value: 'T'} require.Equal(t, "T", o.String()) o = &tengo.String{Value: ""} require.Equal(t, `""`, o.String()) @@ -128,7 +128,7 @@ func TestObject_String(t *testing.T) { } func TestObject_BinaryOp(t *testing.T) { - var o tengo.Object = &tengo.Char{} + var o tengo.Object = tengo.Char{} _, err := o.BinaryOp(token.Add, tengo.UndefinedValue) require.Error(t, err) o = &tengo.Bool{} @@ -172,45 +172,45 @@ func TestArray_BinaryOp(t *testing.T) { &tengo.Array{Value: []tengo.Object{}}) testBinaryOp(t, &tengo.Array{Value: nil}, token.Add, &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 1}, + tengo.Int{Value: 1}, }}, &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 1}, + tengo.Int{Value: 1}, }}) testBinaryOp(t, &tengo.Array{Value: nil}, token.Add, &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}, - &tengo.Int{Value: 3}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}, + tengo.Int{Value: 3}, }}, &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}, - &tengo.Int{Value: 3}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}, + tengo.Int{Value: 3}, }}) testBinaryOp(t, &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}, - &tengo.Int{Value: 3}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}, + tengo.Int{Value: 3}, }}, token.Add, &tengo.Array{Value: nil}, &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}, - &tengo.Int{Value: 3}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}, + tengo.Int{Value: 3}, }}) testBinaryOp(t, &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}, - &tengo.Int{Value: 3}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}, + tengo.Int{Value: 3}, }}, token.Add, &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 4}, - &tengo.Int{Value: 5}, - &tengo.Int{Value: 6}, + tengo.Int{Value: 4}, + tengo.Int{Value: 5}, + tengo.Int{Value: 6}, }}, &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}, - &tengo.Int{Value: 3}, - &tengo.Int{Value: 4}, - &tengo.Int{Value: 5}, - &tengo.Int{Value: 6}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}, + tengo.Int{Value: 3}, + tengo.Int{Value: 4}, + tengo.Int{Value: 5}, + tengo.Int{Value: 6}, }}) } @@ -229,24 +229,24 @@ func TestFloat_BinaryOp(t *testing.T) { // float + float for l := float64(-2); l <= 2.1; l += 0.4 { for r := float64(-2); r <= 2.1; r += 0.4 { - testBinaryOp(t, &tengo.Float{Value: l}, token.Add, - &tengo.Float{Value: r}, &tengo.Float{Value: l + r}) + testBinaryOp(t, tengo.Float{Value: l}, token.Add, + tengo.Float{Value: r}, tengo.Float{Value: l + r}) } } // float - float for l := float64(-2); l <= 2.1; l += 0.4 { for r := float64(-2); r <= 2.1; r += 0.4 { - testBinaryOp(t, &tengo.Float{Value: l}, token.Sub, - &tengo.Float{Value: r}, &tengo.Float{Value: l - r}) + testBinaryOp(t, tengo.Float{Value: l}, token.Sub, + tengo.Float{Value: r}, tengo.Float{Value: l - r}) } } // float * float for l := float64(-2); l <= 2.1; l += 0.4 { for r := float64(-2); r <= 2.1; r += 0.4 { - testBinaryOp(t, &tengo.Float{Value: l}, token.Mul, - &tengo.Float{Value: r}, &tengo.Float{Value: l * r}) + testBinaryOp(t, tengo.Float{Value: l}, token.Mul, + tengo.Float{Value: r}, tengo.Float{Value: l * r}) } } @@ -254,8 +254,8 @@ func TestFloat_BinaryOp(t *testing.T) { for l := float64(-2); l <= 2.1; l += 0.4 { for r := float64(-2); r <= 2.1; r += 0.4 { if r != 0 { - testBinaryOp(t, &tengo.Float{Value: l}, token.Quo, - &tengo.Float{Value: r}, &tengo.Float{Value: l / r}) + testBinaryOp(t, tengo.Float{Value: l}, token.Quo, + tengo.Float{Value: r}, tengo.Float{Value: l / r}) } } } @@ -263,56 +263,56 @@ func TestFloat_BinaryOp(t *testing.T) { // float < float for l := float64(-2); l <= 2.1; l += 0.4 { for r := float64(-2); r <= 2.1; r += 0.4 { - testBinaryOp(t, &tengo.Float{Value: l}, token.Less, - &tengo.Float{Value: r}, boolValue(l < r)) + testBinaryOp(t, tengo.Float{Value: l}, token.Less, + tengo.Float{Value: r}, boolValue(l < r)) } } // float > float for l := float64(-2); l <= 2.1; l += 0.4 { for r := float64(-2); r <= 2.1; r += 0.4 { - testBinaryOp(t, &tengo.Float{Value: l}, token.Greater, - &tengo.Float{Value: r}, boolValue(l > r)) + testBinaryOp(t, tengo.Float{Value: l}, token.Greater, + tengo.Float{Value: r}, boolValue(l > r)) } } // float <= float for l := float64(-2); l <= 2.1; l += 0.4 { for r := float64(-2); r <= 2.1; r += 0.4 { - testBinaryOp(t, &tengo.Float{Value: l}, token.LessEq, - &tengo.Float{Value: r}, boolValue(l <= r)) + testBinaryOp(t, tengo.Float{Value: l}, token.LessEq, + tengo.Float{Value: r}, boolValue(l <= r)) } } // float >= float for l := float64(-2); l <= 2.1; l += 0.4 { for r := float64(-2); r <= 2.1; r += 0.4 { - testBinaryOp(t, &tengo.Float{Value: l}, token.GreaterEq, - &tengo.Float{Value: r}, boolValue(l >= r)) + testBinaryOp(t, tengo.Float{Value: l}, token.GreaterEq, + tengo.Float{Value: r}, boolValue(l >= r)) } } // float + int for l := float64(-2); l <= 2.1; l += 0.4 { for r := int64(-2); r <= 2; r++ { - testBinaryOp(t, &tengo.Float{Value: l}, token.Add, - &tengo.Int{Value: r}, &tengo.Float{Value: l + float64(r)}) + testBinaryOp(t, tengo.Float{Value: l}, token.Add, + tengo.Int{Value: r}, tengo.Float{Value: l + float64(r)}) } } // float - int for l := float64(-2); l <= 2.1; l += 0.4 { for r := int64(-2); r <= 2; r++ { - testBinaryOp(t, &tengo.Float{Value: l}, token.Sub, - &tengo.Int{Value: r}, &tengo.Float{Value: l - float64(r)}) + testBinaryOp(t, tengo.Float{Value: l}, token.Sub, + tengo.Int{Value: r}, tengo.Float{Value: l - float64(r)}) } } // float * int for l := float64(-2); l <= 2.1; l += 0.4 { for r := int64(-2); r <= 2; r++ { - testBinaryOp(t, &tengo.Float{Value: l}, token.Mul, - &tengo.Int{Value: r}, &tengo.Float{Value: l * float64(r)}) + testBinaryOp(t, tengo.Float{Value: l}, token.Mul, + tengo.Int{Value: r}, tengo.Float{Value: l * float64(r)}) } } @@ -320,9 +320,9 @@ func TestFloat_BinaryOp(t *testing.T) { for l := float64(-2); l <= 2.1; l += 0.4 { for r := int64(-2); r <= 2; r++ { if r != 0 { - testBinaryOp(t, &tengo.Float{Value: l}, token.Quo, - &tengo.Int{Value: r}, - &tengo.Float{Value: l / float64(r)}) + testBinaryOp(t, tengo.Float{Value: l}, token.Quo, + tengo.Int{Value: r}, + tengo.Float{Value: l / float64(r)}) } } } @@ -330,32 +330,32 @@ func TestFloat_BinaryOp(t *testing.T) { // float < int for l := float64(-2); l <= 2.1; l += 0.4 { for r := int64(-2); r <= 2; r++ { - testBinaryOp(t, &tengo.Float{Value: l}, token.Less, - &tengo.Int{Value: r}, boolValue(l < float64(r))) + testBinaryOp(t, tengo.Float{Value: l}, token.Less, + tengo.Int{Value: r}, boolValue(l < float64(r))) } } // float > int for l := float64(-2); l <= 2.1; l += 0.4 { for r := int64(-2); r <= 2; r++ { - testBinaryOp(t, &tengo.Float{Value: l}, token.Greater, - &tengo.Int{Value: r}, boolValue(l > float64(r))) + testBinaryOp(t, tengo.Float{Value: l}, token.Greater, + tengo.Int{Value: r}, boolValue(l > float64(r))) } } // float <= int for l := float64(-2); l <= 2.1; l += 0.4 { for r := int64(-2); r <= 2; r++ { - testBinaryOp(t, &tengo.Float{Value: l}, token.LessEq, - &tengo.Int{Value: r}, boolValue(l <= float64(r))) + testBinaryOp(t, tengo.Float{Value: l}, token.LessEq, + tengo.Int{Value: r}, boolValue(l <= float64(r))) } } // float >= int for l := float64(-2); l <= 2.1; l += 0.4 { for r := int64(-2); r <= 2; r++ { - testBinaryOp(t, &tengo.Float{Value: l}, token.GreaterEq, - &tengo.Int{Value: r}, boolValue(l >= float64(r))) + testBinaryOp(t, tengo.Float{Value: l}, token.GreaterEq, + tengo.Int{Value: r}, boolValue(l >= float64(r))) } } } @@ -364,24 +364,24 @@ func TestInt_BinaryOp(t *testing.T) { // int + int for l := int64(-2); l <= 2; l++ { for r := int64(-2); r <= 2; r++ { - testBinaryOp(t, &tengo.Int{Value: l}, token.Add, - &tengo.Int{Value: r}, &tengo.Int{Value: l + r}) + testBinaryOp(t, tengo.Int{Value: l}, token.Add, + tengo.Int{Value: r}, tengo.Int{Value: l + r}) } } // int - int for l := int64(-2); l <= 2; l++ { for r := int64(-2); r <= 2; r++ { - testBinaryOp(t, &tengo.Int{Value: l}, token.Sub, - &tengo.Int{Value: r}, &tengo.Int{Value: l - r}) + testBinaryOp(t, tengo.Int{Value: l}, token.Sub, + tengo.Int{Value: r}, tengo.Int{Value: l - r}) } } // int * int for l := int64(-2); l <= 2; l++ { for r := int64(-2); r <= 2; r++ { - testBinaryOp(t, &tengo.Int{Value: l}, token.Mul, - &tengo.Int{Value: r}, &tengo.Int{Value: l * r}) + testBinaryOp(t, tengo.Int{Value: l}, token.Mul, + tengo.Int{Value: r}, tengo.Int{Value: l * r}) } } @@ -389,8 +389,8 @@ func TestInt_BinaryOp(t *testing.T) { for l := int64(-2); l <= 2; l++ { for r := int64(-2); r <= 2; r++ { if r != 0 { - testBinaryOp(t, &tengo.Int{Value: l}, token.Quo, - &tengo.Int{Value: r}, &tengo.Int{Value: l / r}) + testBinaryOp(t, tengo.Int{Value: l}, token.Quo, + tengo.Int{Value: r}, tengo.Int{Value: l / r}) } } } @@ -399,243 +399,243 @@ func TestInt_BinaryOp(t *testing.T) { for l := int64(-4); l <= 4; l++ { for r := -int64(-4); r <= 4; r++ { if r == 0 { - testBinaryOp(t, &tengo.Int{Value: l}, token.Rem, - &tengo.Int{Value: r}, &tengo.Int{Value: l % r}) + testBinaryOp(t, tengo.Int{Value: l}, token.Rem, + tengo.Int{Value: r}, tengo.Int{Value: l % r}) } } } // int & int testBinaryOp(t, - &tengo.Int{Value: 0}, token.And, &tengo.Int{Value: 0}, - &tengo.Int{Value: int64(0)}) + tengo.Int{Value: 0}, token.And, tengo.Int{Value: 0}, + tengo.Int{Value: int64(0)}) testBinaryOp(t, - &tengo.Int{Value: 1}, token.And, &tengo.Int{Value: 0}, - &tengo.Int{Value: int64(1) & int64(0)}) + tengo.Int{Value: 1}, token.And, tengo.Int{Value: 0}, + tengo.Int{Value: int64(1) & int64(0)}) testBinaryOp(t, - &tengo.Int{Value: 0}, token.And, &tengo.Int{Value: 1}, - &tengo.Int{Value: int64(0) & int64(1)}) + tengo.Int{Value: 0}, token.And, tengo.Int{Value: 1}, + tengo.Int{Value: int64(0) & int64(1)}) testBinaryOp(t, - &tengo.Int{Value: 1}, token.And, &tengo.Int{Value: 1}, - &tengo.Int{Value: int64(1)}) + tengo.Int{Value: 1}, token.And, tengo.Int{Value: 1}, + tengo.Int{Value: int64(1)}) testBinaryOp(t, - &tengo.Int{Value: 0}, token.And, &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(0) & int64(0xffffffff)}) + tengo.Int{Value: 0}, token.And, tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(0) & int64(0xffffffff)}) testBinaryOp(t, - &tengo.Int{Value: 1}, token.And, &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(1) & int64(0xffffffff)}) + tengo.Int{Value: 1}, token.And, tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(1) & int64(0xffffffff)}) testBinaryOp(t, - &tengo.Int{Value: int64(0xffffffff)}, token.And, - &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(0xffffffff)}) + tengo.Int{Value: int64(0xffffffff)}, token.And, + tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(0xffffffff)}) testBinaryOp(t, - &tengo.Int{Value: 1984}, token.And, - &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(1984) & int64(0xffffffff)}) - testBinaryOp(t, &tengo.Int{Value: -1984}, token.And, - &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(-1984) & int64(0xffffffff)}) + tengo.Int{Value: 1984}, token.And, + tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(1984) & int64(0xffffffff)}) + testBinaryOp(t, tengo.Int{Value: -1984}, token.And, + tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(-1984) & int64(0xffffffff)}) // int | int testBinaryOp(t, - &tengo.Int{Value: 0}, token.Or, &tengo.Int{Value: 0}, - &tengo.Int{Value: int64(0)}) + tengo.Int{Value: 0}, token.Or, tengo.Int{Value: 0}, + tengo.Int{Value: int64(0)}) testBinaryOp(t, - &tengo.Int{Value: 1}, token.Or, &tengo.Int{Value: 0}, - &tengo.Int{Value: int64(1) | int64(0)}) + tengo.Int{Value: 1}, token.Or, tengo.Int{Value: 0}, + tengo.Int{Value: int64(1) | int64(0)}) testBinaryOp(t, - &tengo.Int{Value: 0}, token.Or, &tengo.Int{Value: 1}, - &tengo.Int{Value: int64(0) | int64(1)}) + tengo.Int{Value: 0}, token.Or, tengo.Int{Value: 1}, + tengo.Int{Value: int64(0) | int64(1)}) testBinaryOp(t, - &tengo.Int{Value: 1}, token.Or, &tengo.Int{Value: 1}, - &tengo.Int{Value: int64(1)}) + tengo.Int{Value: 1}, token.Or, tengo.Int{Value: 1}, + tengo.Int{Value: int64(1)}) testBinaryOp(t, - &tengo.Int{Value: 0}, token.Or, &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(0) | int64(0xffffffff)}) + tengo.Int{Value: 0}, token.Or, tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(0) | int64(0xffffffff)}) testBinaryOp(t, - &tengo.Int{Value: 1}, token.Or, &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(1) | int64(0xffffffff)}) + tengo.Int{Value: 1}, token.Or, tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(1) | int64(0xffffffff)}) testBinaryOp(t, - &tengo.Int{Value: int64(0xffffffff)}, token.Or, - &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(0xffffffff)}) + tengo.Int{Value: int64(0xffffffff)}, token.Or, + tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(0xffffffff)}) testBinaryOp(t, - &tengo.Int{Value: 1984}, token.Or, - &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(1984) | int64(0xffffffff)}) + tengo.Int{Value: 1984}, token.Or, + tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(1984) | int64(0xffffffff)}) testBinaryOp(t, - &tengo.Int{Value: -1984}, token.Or, - &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(-1984) | int64(0xffffffff)}) + tengo.Int{Value: -1984}, token.Or, + tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(-1984) | int64(0xffffffff)}) // int ^ int testBinaryOp(t, - &tengo.Int{Value: 0}, token.Xor, &tengo.Int{Value: 0}, - &tengo.Int{Value: int64(0)}) + tengo.Int{Value: 0}, token.Xor, tengo.Int{Value: 0}, + tengo.Int{Value: int64(0)}) testBinaryOp(t, - &tengo.Int{Value: 1}, token.Xor, &tengo.Int{Value: 0}, - &tengo.Int{Value: int64(1) ^ int64(0)}) + tengo.Int{Value: 1}, token.Xor, tengo.Int{Value: 0}, + tengo.Int{Value: int64(1) ^ int64(0)}) testBinaryOp(t, - &tengo.Int{Value: 0}, token.Xor, &tengo.Int{Value: 1}, - &tengo.Int{Value: int64(0) ^ int64(1)}) + tengo.Int{Value: 0}, token.Xor, tengo.Int{Value: 1}, + tengo.Int{Value: int64(0) ^ int64(1)}) testBinaryOp(t, - &tengo.Int{Value: 1}, token.Xor, &tengo.Int{Value: 1}, - &tengo.Int{Value: int64(0)}) + tengo.Int{Value: 1}, token.Xor, tengo.Int{Value: 1}, + tengo.Int{Value: int64(0)}) testBinaryOp(t, - &tengo.Int{Value: 0}, token.Xor, &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(0) ^ int64(0xffffffff)}) + tengo.Int{Value: 0}, token.Xor, tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(0) ^ int64(0xffffffff)}) testBinaryOp(t, - &tengo.Int{Value: 1}, token.Xor, &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(1) ^ int64(0xffffffff)}) + tengo.Int{Value: 1}, token.Xor, tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(1) ^ int64(0xffffffff)}) testBinaryOp(t, - &tengo.Int{Value: int64(0xffffffff)}, token.Xor, - &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(0)}) + tengo.Int{Value: int64(0xffffffff)}, token.Xor, + tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(0)}) testBinaryOp(t, - &tengo.Int{Value: 1984}, token.Xor, - &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(1984) ^ int64(0xffffffff)}) + tengo.Int{Value: 1984}, token.Xor, + tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(1984) ^ int64(0xffffffff)}) testBinaryOp(t, - &tengo.Int{Value: -1984}, token.Xor, - &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(-1984) ^ int64(0xffffffff)}) + tengo.Int{Value: -1984}, token.Xor, + tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(-1984) ^ int64(0xffffffff)}) // int &^ int testBinaryOp(t, - &tengo.Int{Value: 0}, token.AndNot, &tengo.Int{Value: 0}, - &tengo.Int{Value: int64(0)}) + tengo.Int{Value: 0}, token.AndNot, tengo.Int{Value: 0}, + tengo.Int{Value: int64(0)}) testBinaryOp(t, - &tengo.Int{Value: 1}, token.AndNot, &tengo.Int{Value: 0}, - &tengo.Int{Value: int64(1) &^ int64(0)}) + tengo.Int{Value: 1}, token.AndNot, tengo.Int{Value: 0}, + tengo.Int{Value: int64(1) &^ int64(0)}) testBinaryOp(t, - &tengo.Int{Value: 0}, token.AndNot, - &tengo.Int{Value: 1}, &tengo.Int{Value: int64(0) &^ int64(1)}) + tengo.Int{Value: 0}, token.AndNot, + tengo.Int{Value: 1}, tengo.Int{Value: int64(0) &^ int64(1)}) testBinaryOp(t, - &tengo.Int{Value: 1}, token.AndNot, &tengo.Int{Value: 1}, - &tengo.Int{Value: int64(0)}) + tengo.Int{Value: 1}, token.AndNot, tengo.Int{Value: 1}, + tengo.Int{Value: int64(0)}) testBinaryOp(t, - &tengo.Int{Value: 0}, token.AndNot, - &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(0) &^ int64(0xffffffff)}) + tengo.Int{Value: 0}, token.AndNot, + tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(0) &^ int64(0xffffffff)}) testBinaryOp(t, - &tengo.Int{Value: 1}, token.AndNot, - &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(1) &^ int64(0xffffffff)}) + tengo.Int{Value: 1}, token.AndNot, + tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(1) &^ int64(0xffffffff)}) testBinaryOp(t, - &tengo.Int{Value: int64(0xffffffff)}, token.AndNot, - &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(0)}) + tengo.Int{Value: int64(0xffffffff)}, token.AndNot, + tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(0)}) testBinaryOp(t, - &tengo.Int{Value: 1984}, token.AndNot, - &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(1984) &^ int64(0xffffffff)}) + tengo.Int{Value: 1984}, token.AndNot, + tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(1984) &^ int64(0xffffffff)}) testBinaryOp(t, - &tengo.Int{Value: -1984}, token.AndNot, - &tengo.Int{Value: int64(0xffffffff)}, - &tengo.Int{Value: int64(-1984) &^ int64(0xffffffff)}) + tengo.Int{Value: -1984}, token.AndNot, + tengo.Int{Value: int64(0xffffffff)}, + tengo.Int{Value: int64(-1984) &^ int64(0xffffffff)}) // int << int for s := int64(0); s < 64; s++ { testBinaryOp(t, - &tengo.Int{Value: 0}, token.Shl, &tengo.Int{Value: s}, - &tengo.Int{Value: int64(0) << uint(s)}) + tengo.Int{Value: 0}, token.Shl, tengo.Int{Value: s}, + tengo.Int{Value: int64(0) << uint(s)}) testBinaryOp(t, - &tengo.Int{Value: 1}, token.Shl, &tengo.Int{Value: s}, - &tengo.Int{Value: int64(1) << uint(s)}) + tengo.Int{Value: 1}, token.Shl, tengo.Int{Value: s}, + tengo.Int{Value: int64(1) << uint(s)}) testBinaryOp(t, - &tengo.Int{Value: 2}, token.Shl, &tengo.Int{Value: s}, - &tengo.Int{Value: int64(2) << uint(s)}) + tengo.Int{Value: 2}, token.Shl, tengo.Int{Value: s}, + tengo.Int{Value: int64(2) << uint(s)}) testBinaryOp(t, - &tengo.Int{Value: -1}, token.Shl, &tengo.Int{Value: s}, - &tengo.Int{Value: int64(-1) << uint(s)}) + tengo.Int{Value: -1}, token.Shl, tengo.Int{Value: s}, + tengo.Int{Value: int64(-1) << uint(s)}) testBinaryOp(t, - &tengo.Int{Value: -2}, token.Shl, &tengo.Int{Value: s}, - &tengo.Int{Value: int64(-2) << uint(s)}) + tengo.Int{Value: -2}, token.Shl, tengo.Int{Value: s}, + tengo.Int{Value: int64(-2) << uint(s)}) testBinaryOp(t, - &tengo.Int{Value: int64(0xffffffff)}, token.Shl, - &tengo.Int{Value: s}, - &tengo.Int{Value: int64(0xffffffff) << uint(s)}) + tengo.Int{Value: int64(0xffffffff)}, token.Shl, + tengo.Int{Value: s}, + tengo.Int{Value: int64(0xffffffff) << uint(s)}) } // int >> int for s := int64(0); s < 64; s++ { testBinaryOp(t, - &tengo.Int{Value: 0}, token.Shr, &tengo.Int{Value: s}, - &tengo.Int{Value: int64(0) >> uint(s)}) + tengo.Int{Value: 0}, token.Shr, tengo.Int{Value: s}, + tengo.Int{Value: int64(0) >> uint(s)}) testBinaryOp(t, - &tengo.Int{Value: 1}, token.Shr, &tengo.Int{Value: s}, - &tengo.Int{Value: int64(1) >> uint(s)}) + tengo.Int{Value: 1}, token.Shr, tengo.Int{Value: s}, + tengo.Int{Value: int64(1) >> uint(s)}) testBinaryOp(t, - &tengo.Int{Value: 2}, token.Shr, &tengo.Int{Value: s}, - &tengo.Int{Value: int64(2) >> uint(s)}) + tengo.Int{Value: 2}, token.Shr, tengo.Int{Value: s}, + tengo.Int{Value: int64(2) >> uint(s)}) testBinaryOp(t, - &tengo.Int{Value: -1}, token.Shr, &tengo.Int{Value: s}, - &tengo.Int{Value: int64(-1) >> uint(s)}) + tengo.Int{Value: -1}, token.Shr, tengo.Int{Value: s}, + tengo.Int{Value: int64(-1) >> uint(s)}) testBinaryOp(t, - &tengo.Int{Value: -2}, token.Shr, &tengo.Int{Value: s}, - &tengo.Int{Value: int64(-2) >> uint(s)}) + tengo.Int{Value: -2}, token.Shr, tengo.Int{Value: s}, + tengo.Int{Value: int64(-2) >> uint(s)}) testBinaryOp(t, - &tengo.Int{Value: int64(0xffffffff)}, token.Shr, - &tengo.Int{Value: s}, - &tengo.Int{Value: int64(0xffffffff) >> uint(s)}) + tengo.Int{Value: int64(0xffffffff)}, token.Shr, + tengo.Int{Value: s}, + tengo.Int{Value: int64(0xffffffff) >> uint(s)}) } // int < int for l := int64(-2); l <= 2; l++ { for r := int64(-2); r <= 2; r++ { - testBinaryOp(t, &tengo.Int{Value: l}, token.Less, - &tengo.Int{Value: r}, boolValue(l < r)) + testBinaryOp(t, tengo.Int{Value: l}, token.Less, + tengo.Int{Value: r}, boolValue(l < r)) } } // int > int for l := int64(-2); l <= 2; l++ { for r := int64(-2); r <= 2; r++ { - testBinaryOp(t, &tengo.Int{Value: l}, token.Greater, - &tengo.Int{Value: r}, boolValue(l > r)) + testBinaryOp(t, tengo.Int{Value: l}, token.Greater, + tengo.Int{Value: r}, boolValue(l > r)) } } // int <= int for l := int64(-2); l <= 2; l++ { for r := int64(-2); r <= 2; r++ { - testBinaryOp(t, &tengo.Int{Value: l}, token.LessEq, - &tengo.Int{Value: r}, boolValue(l <= r)) + testBinaryOp(t, tengo.Int{Value: l}, token.LessEq, + tengo.Int{Value: r}, boolValue(l <= r)) } } // int >= int for l := int64(-2); l <= 2; l++ { for r := int64(-2); r <= 2; r++ { - testBinaryOp(t, &tengo.Int{Value: l}, token.GreaterEq, - &tengo.Int{Value: r}, boolValue(l >= r)) + testBinaryOp(t, tengo.Int{Value: l}, token.GreaterEq, + tengo.Int{Value: r}, boolValue(l >= r)) } } // int + float for l := int64(-2); l <= 2; l++ { for r := float64(-2); r <= 2.1; r += 0.5 { - testBinaryOp(t, &tengo.Int{Value: l}, token.Add, - &tengo.Float{Value: r}, - &tengo.Float{Value: float64(l) + r}) + testBinaryOp(t, tengo.Int{Value: l}, token.Add, + tengo.Float{Value: r}, + tengo.Float{Value: float64(l) + r}) } } // int - float for l := int64(-2); l <= 2; l++ { for r := float64(-2); r <= 2.1; r += 0.5 { - testBinaryOp(t, &tengo.Int{Value: l}, token.Sub, - &tengo.Float{Value: r}, - &tengo.Float{Value: float64(l) - r}) + testBinaryOp(t, tengo.Int{Value: l}, token.Sub, + tengo.Float{Value: r}, + tengo.Float{Value: float64(l) - r}) } } // int * float for l := int64(-2); l <= 2; l++ { for r := float64(-2); r <= 2.1; r += 0.5 { - testBinaryOp(t, &tengo.Int{Value: l}, token.Mul, - &tengo.Float{Value: r}, - &tengo.Float{Value: float64(l) * r}) + testBinaryOp(t, tengo.Int{Value: l}, token.Mul, + tengo.Float{Value: r}, + tengo.Float{Value: float64(l) * r}) } } @@ -643,9 +643,9 @@ func TestInt_BinaryOp(t *testing.T) { for l := int64(-2); l <= 2; l++ { for r := float64(-2); r <= 2.1; r += 0.5 { if r != 0 { - testBinaryOp(t, &tengo.Int{Value: l}, token.Quo, - &tengo.Float{Value: r}, - &tengo.Float{Value: float64(l) / r}) + testBinaryOp(t, tengo.Int{Value: l}, token.Quo, + tengo.Float{Value: r}, + tengo.Float{Value: float64(l) / r}) } } } @@ -653,39 +653,39 @@ func TestInt_BinaryOp(t *testing.T) { // int < float for l := int64(-2); l <= 2; l++ { for r := float64(-2); r <= 2.1; r += 0.5 { - testBinaryOp(t, &tengo.Int{Value: l}, token.Less, - &tengo.Float{Value: r}, boolValue(float64(l) < r)) + testBinaryOp(t, tengo.Int{Value: l}, token.Less, + tengo.Float{Value: r}, boolValue(float64(l) < r)) } } // int > float for l := int64(-2); l <= 2; l++ { for r := float64(-2); r <= 2.1; r += 0.5 { - testBinaryOp(t, &tengo.Int{Value: l}, token.Greater, - &tengo.Float{Value: r}, boolValue(float64(l) > r)) + testBinaryOp(t, tengo.Int{Value: l}, token.Greater, + tengo.Float{Value: r}, boolValue(float64(l) > r)) } } // int <= float for l := int64(-2); l <= 2; l++ { for r := float64(-2); r <= 2.1; r += 0.5 { - testBinaryOp(t, &tengo.Int{Value: l}, token.LessEq, - &tengo.Float{Value: r}, boolValue(float64(l) <= r)) + testBinaryOp(t, tengo.Int{Value: l}, token.LessEq, + tengo.Float{Value: r}, boolValue(float64(l) <= r)) } } // int >= float for l := int64(-2); l <= 2; l++ { for r := float64(-2); r <= 2.1; r += 0.5 { - testBinaryOp(t, &tengo.Int{Value: l}, token.GreaterEq, - &tengo.Float{Value: r}, boolValue(float64(l) >= r)) + testBinaryOp(t, tengo.Int{Value: l}, token.GreaterEq, + tengo.Float{Value: r}, boolValue(float64(l) >= r)) } } } func TestMap_Index(t *testing.T) { m := &tengo.Map{Value: make(map[string]tengo.Object)} - k := &tengo.Int{Value: 1} + k := tengo.Int{Value: 1} v := &tengo.String{Value: "abcdef"} err := m.IndexSet(k, v) @@ -709,7 +709,7 @@ func TestString_BinaryOp(t *testing.T) { rc := []rune(rstr)[r] testBinaryOp(t, &tengo.String{Value: ls}, token.Add, - &tengo.Char{Value: rc}, + tengo.Char{Value: rc}, &tengo.String{Value: ls + string(rc)}) } } diff --git a/require/require.go b/require/require.go index 99c1a7ce..ea3835c9 100644 --- a/require/require.go +++ b/require/require.go @@ -134,14 +134,14 @@ func Equal( } case []tengo.Object: equalObjectSlice(t, expected, actual.([]tengo.Object), msg...) - case *tengo.Int: - Equal(t, expected.Value, actual.(*tengo.Int).Value, msg...) - case *tengo.Float: - Equal(t, expected.Value, actual.(*tengo.Float).Value, msg...) + case tengo.Int: + Equal(t, expected.Value, actual.(tengo.Int).Value, msg...) + case tengo.Float: + Equal(t, expected.Value, actual.(tengo.Float).Value, msg...) case *tengo.String: Equal(t, expected.Value, actual.(*tengo.String).Value, msg...) - case *tengo.Char: - Equal(t, expected.Value, actual.(*tengo.Char).Value, msg...) + case tengo.Char: + Equal(t, expected.Value, actual.(tengo.Char).Value, msg...) case *tengo.Bool: if expected != actual { failExpectedActual(t, expected, actual, msg...) diff --git a/script_test.go b/script_test.go index 5e8f3630..d0203dc1 100644 --- a/script_test.go +++ b/script_test.go @@ -24,12 +24,12 @@ func TestScript_Add(t *testing.T) { func(args ...tengo.Object) (ret tengo.Object, err error) { if len(args) > 0 { switch arg := args[0].(type) { - case *tengo.Int: - return &tengo.Int{Value: arg.Value + 1}, nil + case tengo.Int: + return tengo.Int{Value: arg.Value + 1}, nil } } - return &tengo.Int{Value: 0}, nil + return tengo.Int{Value: 0}, nil })) c, err := s.Compile() require.NoError(t, err) @@ -177,7 +177,7 @@ e := mod1.double(s) err error, ) { arg0, _ := tengo.ToInt64(args[0]) - ret = &tengo.Int{Value: arg0 * 2} + ret = tengo.Int{Value: arg0 * 2} return }, }, @@ -227,7 +227,7 @@ e := mod1.double(s) } type Counter struct { - tengo.ObjectImpl + tengo.PtrObjectImpl value int64 } @@ -251,7 +251,7 @@ func (o *Counter) BinaryOp( case token.Sub: return &Counter{value: o.value - rhs.value}, nil } - case *tengo.Int: + case tengo.Int: switch op { case token.Add: return &Counter{value: o.value + rhs.Value}, nil @@ -280,7 +280,7 @@ func (o *Counter) Copy() tengo.Object { } func (o *Counter) Call(_ ...tengo.Object) (tengo.Object, error) { - return &tengo.Int{Value: o.value}, nil + return tengo.Int{Value: o.value}, nil } func (o *Counter) CanCall() bool { diff --git a/stdlib/func_typedefs.go b/stdlib/func_typedefs.go index fdac933c..5ff6c0e4 100644 --- a/stdlib/func_typedefs.go +++ b/stdlib/func_typedefs.go @@ -24,7 +24,7 @@ func FuncARI(fn func() int) tengo.CallableFunc { if len(args) != 0 { return nil, tengo.ErrWrongNumArguments } - return &tengo.Int{Value: int64(fn())}, nil + return tengo.Int{Value: int64(fn())}, nil } } @@ -35,7 +35,7 @@ func FuncARI64(fn func() int64) tengo.CallableFunc { if len(args) != 0 { return nil, tengo.ErrWrongNumArguments } - return &tengo.Int{Value: fn()}, nil + return tengo.Int{Value: fn()}, nil } } @@ -55,7 +55,7 @@ func FuncAI64RI64(fn func(int64) int64) tengo.CallableFunc { Found: args[0].TypeName(), } } - return &tengo.Int{Value: fn(i1)}, nil + return tengo.Int{Value: fn(i1)}, nil } } @@ -163,7 +163,7 @@ func FuncARF(fn func() float64) tengo.CallableFunc { if len(args) != 0 { return nil, tengo.ErrWrongNumArguments } - return &tengo.Float{Value: fn()}, nil + return tengo.Float{Value: fn()}, nil } } @@ -198,7 +198,7 @@ func FuncARIsE(fn func() ([]int, error)) tengo.CallableFunc { } arr := &tengo.Array{} for _, v := range res { - arr.Value = append(arr.Value, &tengo.Int{Value: int64(v)}) + arr.Value = append(arr.Value, tengo.Int{Value: int64(v)}) } return arr, nil } @@ -222,7 +222,7 @@ func FuncAIRIs(fn func(int) []int) tengo.CallableFunc { res := fn(i1) arr := &tengo.Array{} for _, v := range res { - arr.Value = append(arr.Value, &tengo.Int{Value: int64(v)}) + arr.Value = append(arr.Value, tengo.Int{Value: int64(v)}) } return arr, nil } @@ -243,7 +243,7 @@ func FuncAFRF(fn func(float64) float64) tengo.CallableFunc { Found: args[0].TypeName(), } } - return &tengo.Float{Value: fn(f1)}, nil + return tengo.Float{Value: fn(f1)}, nil } } @@ -281,7 +281,7 @@ func FuncAIRF(fn func(int) float64) tengo.CallableFunc { Found: args[0].TypeName(), } } - return &tengo.Float{Value: fn(i1)}, nil + return tengo.Float{Value: fn(i1)}, nil } } @@ -300,7 +300,7 @@ func FuncAFRI(fn func(float64) int) tengo.CallableFunc { Found: args[0].TypeName(), } } - return &tengo.Int{Value: int64(fn(f1))}, nil + return tengo.Int{Value: int64(fn(f1))}, nil } } @@ -327,7 +327,7 @@ func FuncAFFRF(fn func(float64, float64) float64) tengo.CallableFunc { Found: args[1].TypeName(), } } - return &tengo.Float{Value: fn(f1, f2)}, nil + return tengo.Float{Value: fn(f1, f2)}, nil } } @@ -354,7 +354,7 @@ func FuncAIFRF(fn func(int, float64) float64) tengo.CallableFunc { Found: args[1].TypeName(), } } - return &tengo.Float{Value: fn(i1, f2)}, nil + return tengo.Float{Value: fn(i1, f2)}, nil } } @@ -381,7 +381,7 @@ func FuncAFIRF(fn func(float64, int) float64) tengo.CallableFunc { Found: args[1].TypeName(), } } - return &tengo.Float{Value: fn(f1, i2)}, nil + return tengo.Float{Value: fn(f1, i2)}, nil } } @@ -662,7 +662,7 @@ func FuncASSRI(fn func(string, string) int) tengo.CallableFunc { Found: args[0].TypeName(), } } - return &tengo.Int{Value: int64(fn(s1, s2))}, nil + return tengo.Int{Value: int64(fn(s1, s2))}, nil } } @@ -922,7 +922,7 @@ func FuncAYRIE(fn func([]byte) (int, error)) tengo.CallableFunc { if err != nil { return wrapError(err), nil } - return &tengo.Int{Value: int64(res)}, nil + return tengo.Int{Value: int64(res)}, nil } } @@ -965,7 +965,7 @@ func FuncASRIE(fn func(string) (int, error)) tengo.CallableFunc { if err != nil { return wrapError(err), nil } - return &tengo.Int{Value: int64(res)}, nil + return tengo.Int{Value: int64(res)}, nil } } diff --git a/stdlib/func_typedefs_test.go b/stdlib/func_typedefs_test.go index 091c5c47..158a2f52 100644 --- a/stdlib/func_typedefs_test.go +++ b/stdlib/func_typedefs_test.go @@ -13,7 +13,7 @@ import ( func TestFuncAIR(t *testing.T) { uf := stdlib.FuncAIR(func(int) {}) - ret, err := funcCall(uf, &tengo.Int{Value: 10}) + ret, err := funcCall(uf, tengo.Int{Value: 10}) require.NoError(t, err) require.Equal(t, tengo.UndefinedValue, ret) _, err = funcCall(uf) @@ -33,7 +33,7 @@ func TestFuncARI(t *testing.T) { uf := stdlib.FuncARI(func() int { return 10 }) ret, err := funcCall(uf) require.NoError(t, err) - require.Equal(t, &tengo.Int{Value: 10}, ret) + require.Equal(t, tengo.Int{Value: 10}, ret) _, err = funcCall(uf, tengo.TrueValue) require.Equal(t, tengo.ErrWrongNumArguments, err) } @@ -59,8 +59,8 @@ func TestFuncARIsE(t *testing.T) { }) ret, err := funcCall(uf) require.NoError(t, err) - require.Equal(t, array(&tengo.Int{Value: 1}, - &tengo.Int{Value: 2}, &tengo.Int{Value: 3}), ret) + require.Equal(t, array(tengo.Int{Value: 1}, + tengo.Int{Value: 2}, tengo.Int{Value: 3}), ret) uf = stdlib.FuncARIsE(func() ([]int, error) { return nil, errors.New("some error") }) @@ -146,13 +146,13 @@ func TestFuncASRSs(t *testing.T) { func TestFuncASI64RE(t *testing.T) { uf := stdlib.FuncASI64RE(func(a string, b int64) error { return nil }) - ret, err := funcCall(uf, &tengo.String{Value: "foo"}, &tengo.Int{Value: 5}) + ret, err := funcCall(uf, &tengo.String{Value: "foo"}, tengo.Int{Value: 5}) require.NoError(t, err) require.Equal(t, tengo.TrueValue, ret) uf = stdlib.FuncASI64RE(func(a string, b int64) error { return errors.New("some error") }) - ret, err = funcCall(uf, &tengo.String{Value: "foo"}, &tengo.Int{Value: 5}) + ret, err = funcCall(uf, &tengo.String{Value: "foo"}, tengo.Int{Value: 5}) require.NoError(t, err) require.Equal(t, &tengo.Error{Value: &tengo.String{Value: "some error"}}, ret) @@ -162,13 +162,13 @@ func TestFuncASI64RE(t *testing.T) { func TestFuncAIIRE(t *testing.T) { uf := stdlib.FuncAIIRE(func(a, b int) error { return nil }) - ret, err := funcCall(uf, &tengo.Int{Value: 5}, &tengo.Int{Value: 7}) + ret, err := funcCall(uf, tengo.Int{Value: 5}, tengo.Int{Value: 7}) require.NoError(t, err) require.Equal(t, tengo.TrueValue, ret) uf = stdlib.FuncAIIRE(func(a, b int) error { return errors.New("some error") }) - ret, err = funcCall(uf, &tengo.Int{Value: 5}, &tengo.Int{Value: 7}) + ret, err = funcCall(uf, tengo.Int{Value: 5}, tengo.Int{Value: 7}) require.NoError(t, err) require.Equal(t, &tengo.Error{Value: &tengo.String{Value: "some error"}}, ret) @@ -178,15 +178,15 @@ func TestFuncAIIRE(t *testing.T) { func TestFuncASIIRE(t *testing.T) { uf := stdlib.FuncASIIRE(func(a string, b, c int) error { return nil }) - ret, err := funcCall(uf, &tengo.String{Value: "foo"}, &tengo.Int{Value: 5}, - &tengo.Int{Value: 7}) + ret, err := funcCall(uf, &tengo.String{Value: "foo"}, tengo.Int{Value: 5}, + tengo.Int{Value: 7}) require.NoError(t, err) require.Equal(t, tengo.TrueValue, ret) uf = stdlib.FuncASIIRE(func(a string, b, c int) error { return errors.New("some error") }) - ret, err = funcCall(uf, &tengo.String{Value: "foo"}, &tengo.Int{Value: 5}, - &tengo.Int{Value: 7}) + ret, err = funcCall(uf, &tengo.String{Value: "foo"}, tengo.Int{Value: 5}, + tengo.Int{Value: 7}) require.NoError(t, err) require.Equal(t, &tengo.Error{Value: &tengo.String{Value: "some error"}}, ret) @@ -244,16 +244,16 @@ func TestFuncARF(t *testing.T) { uf := stdlib.FuncARF(func() float64 { return 10.0 }) ret, err := funcCall(uf) require.NoError(t, err) - require.Equal(t, &tengo.Float{Value: 10.0}, ret) + require.Equal(t, tengo.Float{Value: 10.0}, ret) _, err = funcCall(uf, tengo.TrueValue) require.Equal(t, tengo.ErrWrongNumArguments, err) } func TestFuncAFRF(t *testing.T) { uf := stdlib.FuncAFRF(func(a float64) float64 { return a }) - ret, err := funcCall(uf, &tengo.Float{Value: 10.0}) + ret, err := funcCall(uf, tengo.Float{Value: 10.0}) require.NoError(t, err) - require.Equal(t, &tengo.Float{Value: 10.0}, ret) + require.Equal(t, tengo.Float{Value: 10.0}, ret) _, err = funcCall(uf) require.Equal(t, tengo.ErrWrongNumArguments, err) _, err = funcCall(uf, tengo.TrueValue, tengo.TrueValue) @@ -264,9 +264,9 @@ func TestFuncAIRF(t *testing.T) { uf := stdlib.FuncAIRF(func(a int) float64 { return float64(a) }) - ret, err := funcCall(uf, &tengo.Int{Value: 10.0}) + ret, err := funcCall(uf, tengo.Int{Value: 10.0}) require.NoError(t, err) - require.Equal(t, &tengo.Float{Value: 10.0}, ret) + require.Equal(t, tengo.Float{Value: 10.0}, ret) _, err = funcCall(uf) require.Equal(t, tengo.ErrWrongNumArguments, err) _, err = funcCall(uf, tengo.TrueValue, tengo.TrueValue) @@ -277,9 +277,9 @@ func TestFuncAFRI(t *testing.T) { uf := stdlib.FuncAFRI(func(a float64) int { return int(a) }) - ret, err := funcCall(uf, &tengo.Float{Value: 10.5}) + ret, err := funcCall(uf, tengo.Float{Value: 10.5}) require.NoError(t, err) - require.Equal(t, &tengo.Int{Value: 10}, ret) + require.Equal(t, tengo.Int{Value: 10}, ret) _, err = funcCall(uf) require.Equal(t, tengo.ErrWrongNumArguments, err) _, err = funcCall(uf, tengo.TrueValue, tengo.TrueValue) @@ -290,7 +290,7 @@ func TestFuncAFRB(t *testing.T) { uf := stdlib.FuncAFRB(func(a float64) bool { return a > 0.0 }) - ret, err := funcCall(uf, &tengo.Float{Value: 0.1}) + ret, err := funcCall(uf, tengo.Float{Value: 0.1}) require.NoError(t, err) require.Equal(t, tengo.TrueValue, ret) _, err = funcCall(uf) @@ -303,10 +303,10 @@ func TestFuncAFFRF(t *testing.T) { uf := stdlib.FuncAFFRF(func(a, b float64) float64 { return a + b }) - ret, err := funcCall(uf, &tengo.Float{Value: 10.0}, - &tengo.Float{Value: 20.0}) + ret, err := funcCall(uf, tengo.Float{Value: 10.0}, + tengo.Float{Value: 20.0}) require.NoError(t, err) - require.Equal(t, &tengo.Float{Value: 30.0}, ret) + require.Equal(t, tengo.Float{Value: 30.0}, ret) _, err = funcCall(uf) require.Equal(t, tengo.ErrWrongNumArguments, err) _, err = funcCall(uf, tengo.TrueValue) @@ -317,7 +317,7 @@ func TestFuncASIRS(t *testing.T) { uf := stdlib.FuncASIRS(func(a string, b int) string { return strings.Repeat(a, b) }) - ret, err := funcCall(uf, &tengo.String{Value: "ab"}, &tengo.Int{Value: 2}) + ret, err := funcCall(uf, &tengo.String{Value: "ab"}, tengo.Int{Value: 2}) require.NoError(t, err) require.Equal(t, &tengo.String{Value: "abab"}, ret) _, err = funcCall(uf) @@ -330,9 +330,9 @@ func TestFuncAIFRF(t *testing.T) { uf := stdlib.FuncAIFRF(func(a int, b float64) float64 { return float64(a) + b }) - ret, err := funcCall(uf, &tengo.Int{Value: 10}, &tengo.Float{Value: 20.0}) + ret, err := funcCall(uf, tengo.Int{Value: 10}, tengo.Float{Value: 20.0}) require.NoError(t, err) - require.Equal(t, &tengo.Float{Value: 30.0}, ret) + require.Equal(t, tengo.Float{Value: 30.0}, ret) _, err = funcCall(uf) require.Equal(t, tengo.ErrWrongNumArguments, err) _, err = funcCall(uf, tengo.TrueValue) @@ -343,9 +343,9 @@ func TestFuncAFIRF(t *testing.T) { uf := stdlib.FuncAFIRF(func(a float64, b int) float64 { return a + float64(b) }) - ret, err := funcCall(uf, &tengo.Float{Value: 10.0}, &tengo.Int{Value: 20}) + ret, err := funcCall(uf, tengo.Float{Value: 10.0}, tengo.Int{Value: 20}) require.NoError(t, err) - require.Equal(t, &tengo.Float{Value: 30.0}, ret) + require.Equal(t, tengo.Float{Value: 30.0}, ret) _, err = funcCall(uf) require.Equal(t, tengo.ErrWrongNumArguments, err) _, err = funcCall(uf, tengo.TrueValue) @@ -356,7 +356,7 @@ func TestFuncAFIRB(t *testing.T) { uf := stdlib.FuncAFIRB(func(a float64, b int) bool { return a < float64(b) }) - ret, err := funcCall(uf, &tengo.Float{Value: 10.0}, &tengo.Int{Value: 20}) + ret, err := funcCall(uf, tengo.Float{Value: 10.0}, tengo.Int{Value: 20}) require.NoError(t, err) require.Equal(t, tengo.TrueValue, ret) _, err = funcCall(uf) @@ -369,14 +369,14 @@ func TestFuncAIRSsE(t *testing.T) { uf := stdlib.FuncAIRSsE(func(a int) ([]string, error) { return []string{"foo", "bar"}, nil }) - ret, err := funcCall(uf, &tengo.Int{Value: 10}) + ret, err := funcCall(uf, tengo.Int{Value: 10}) require.NoError(t, err) require.Equal(t, array(&tengo.String{Value: "foo"}, &tengo.String{Value: "bar"}), ret) uf = stdlib.FuncAIRSsE(func(a int) ([]string, error) { return nil, errors.New("some error") }) - ret, err = funcCall(uf, &tengo.Int{Value: 10}) + ret, err = funcCall(uf, tengo.Int{Value: 10}) require.NoError(t, err) require.Equal(t, &tengo.Error{Value: &tengo.String{Value: "some error"}}, ret) @@ -402,7 +402,7 @@ func TestFuncASSIRSs(t *testing.T) { return []string{a, b, strconv.Itoa(c)} }) ret, err := funcCall(uf, &tengo.String{Value: "foo"}, - &tengo.String{Value: "bar"}, &tengo.Int{Value: 5}) + &tengo.String{Value: "bar"}, tengo.Int{Value: 5}) require.NoError(t, err) require.Equal(t, array(&tengo.String{Value: "foo"}, &tengo.String{Value: "bar"}, &tengo.String{Value: "5"}), ret) @@ -441,7 +441,7 @@ func TestFuncASRIE(t *testing.T) { uf := stdlib.FuncASRIE(func(a string) (int, error) { return 5, nil }) ret, err := funcCall(uf, &tengo.String{Value: "foo"}) require.NoError(t, err) - require.Equal(t, &tengo.Int{Value: 5}, ret) + require.Equal(t, tengo.Int{Value: 5}, ret) uf = stdlib.FuncASRIE(func(a string) (int, error) { return 0, errors.New("some error") }) @@ -457,7 +457,7 @@ func TestFuncAYRIE(t *testing.T) { uf := stdlib.FuncAYRIE(func(a []byte) (int, error) { return 5, nil }) ret, err := funcCall(uf, &tengo.Bytes{Value: []byte("foo")}) require.NoError(t, err) - require.Equal(t, &tengo.Int{Value: 5}, ret) + require.Equal(t, tengo.Int{Value: 5}, ret) uf = stdlib.FuncAYRIE(func(a []byte) (int, error) { return 0, errors.New("some error") }) @@ -474,7 +474,7 @@ func TestFuncASSRI(t *testing.T) { ret, err := funcCall(uf, &tengo.String{Value: "foo"}, &tengo.String{Value: "bar"}) require.NoError(t, err) - require.Equal(t, &tengo.Int{Value: 6}, ret) + require.Equal(t, tengo.Int{Value: 6}, ret) _, err = funcCall(uf, &tengo.String{Value: "foo"}) require.Equal(t, tengo.ErrWrongNumArguments, err) } @@ -501,7 +501,7 @@ func TestFuncASSRB(t *testing.T) { func TestFuncAIRS(t *testing.T) { uf := stdlib.FuncAIRS(func(a int) string { return strconv.Itoa(a) }) - ret, err := funcCall(uf, &tengo.Int{Value: 55}) + ret, err := funcCall(uf, tengo.Int{Value: 55}) require.NoError(t, err) require.Equal(t, &tengo.String{Value: "55"}, ret) _, err = funcCall(uf) @@ -510,16 +510,16 @@ func TestFuncAIRS(t *testing.T) { func TestFuncAIRIs(t *testing.T) { uf := stdlib.FuncAIRIs(func(a int) []int { return []int{a, a} }) - ret, err := funcCall(uf, &tengo.Int{Value: 55}) + ret, err := funcCall(uf, tengo.Int{Value: 55}) require.NoError(t, err) - require.Equal(t, array(&tengo.Int{Value: 55}, &tengo.Int{Value: 55}), ret) + require.Equal(t, array(tengo.Int{Value: 55}, tengo.Int{Value: 55}), ret) _, err = funcCall(uf) require.Equal(t, tengo.ErrWrongNumArguments, err) } func TestFuncAI64R(t *testing.T) { uf := stdlib.FuncAIR(func(a int) {}) - ret, err := funcCall(uf, &tengo.Int{Value: 55}) + ret, err := funcCall(uf, tengo.Int{Value: 55}) require.NoError(t, err) require.Equal(t, tengo.UndefinedValue, ret) _, err = funcCall(uf) @@ -530,8 +530,8 @@ func TestFuncARI64(t *testing.T) { uf := stdlib.FuncARI64(func() int64 { return 55 }) ret, err := funcCall(uf) require.NoError(t, err) - require.Equal(t, &tengo.Int{Value: 55}, ret) - _, err = funcCall(uf, &tengo.Int{Value: 55}) + require.Equal(t, tengo.Int{Value: 55}, ret) + _, err = funcCall(uf, tengo.Int{Value: 55}) require.Equal(t, tengo.ErrWrongNumArguments, err) } @@ -550,9 +550,9 @@ func TestFuncASsSRS(t *testing.T) { func TestFuncAI64RI64(t *testing.T) { uf := stdlib.FuncAI64RI64(func(a int64) int64 { return a * 2 }) - ret, err := funcCall(uf, &tengo.Int{Value: 55}) + ret, err := funcCall(uf, tengo.Int{Value: 55}) require.NoError(t, err) - require.Equal(t, &tengo.Int{Value: 110}, ret) + require.Equal(t, tengo.Int{Value: 110}, ret) _, err = funcCall(uf) require.Equal(t, tengo.ErrWrongNumArguments, err) } diff --git a/stdlib/json/decode.go b/stdlib/json/decode.go index 6d468ef0..7f48fa4f 100644 --- a/stdlib/json/decode.go +++ b/stdlib/json/decode.go @@ -211,7 +211,7 @@ func (d *decodeState) literal() (tengo.Object, error) { panic(phasePanicMsg) } n, _ := strconv.ParseFloat(string(item), 10) - return &tengo.Float{Value: n}, nil + return tengo.Float{Value: n}, nil } } diff --git a/stdlib/json/encode.go b/stdlib/json/encode.go index 10805b01..8f00318b 100644 --- a/stdlib/json/encode.go +++ b/stdlib/json/encode.go @@ -206,9 +206,9 @@ func Encode(o tengo.Object) ([]byte, error) { base64.StdEncoding.Encode(dst, o.Value) b = append(b, dst...) b = append(b, '"') - case *tengo.Char: + case tengo.Char: b = strconv.AppendInt(b, int64(o.Value), 10) - case *tengo.Float: + case tengo.Float: var y []byte f := o.Value @@ -236,7 +236,7 @@ func Encode(o tengo.Object) ([]byte, error) { } b = append(b, y...) - case *tengo.Int: + case tengo.Int: b = strconv.AppendInt(b, o.Value, 10) case *tengo.String: // string encoding bug is fixed with newly introduced function diff --git a/stdlib/math.go b/stdlib/math.go index 633ea09f..c4aa355e 100644 --- a/stdlib/math.go +++ b/stdlib/math.go @@ -7,17 +7,17 @@ import ( ) var mathModule = map[string]tengo.Object{ - "e": &tengo.Float{Value: math.E}, - "pi": &tengo.Float{Value: math.Pi}, - "phi": &tengo.Float{Value: math.Phi}, - "sqrt2": &tengo.Float{Value: math.Sqrt2}, - "sqrtE": &tengo.Float{Value: math.SqrtE}, - "sqrtPi": &tengo.Float{Value: math.SqrtPi}, - "sqrtPhi": &tengo.Float{Value: math.SqrtPhi}, - "ln2": &tengo.Float{Value: math.Ln2}, - "log2E": &tengo.Float{Value: math.Log2E}, - "ln10": &tengo.Float{Value: math.Ln10}, - "log10E": &tengo.Float{Value: math.Log10E}, + "e": tengo.Float{Value: math.E}, + "pi": tengo.Float{Value: math.Pi}, + "phi": tengo.Float{Value: math.Phi}, + "sqrt2": tengo.Float{Value: math.Sqrt2}, + "sqrtE": tengo.Float{Value: math.SqrtE}, + "sqrtPi": tengo.Float{Value: math.SqrtPi}, + "sqrtPhi": tengo.Float{Value: math.SqrtPhi}, + "ln2": tengo.Float{Value: math.Ln2}, + "log2E": tengo.Float{Value: math.Log2E}, + "ln10": tengo.Float{Value: math.Ln10}, + "log10E": tengo.Float{Value: math.Log10E}, "abs": &tengo.UserFunction{ Name: "abs", Value: FuncAFRF(math.Abs), diff --git a/stdlib/os.go b/stdlib/os.go index 576bc94b..11673acd 100644 --- a/stdlib/os.go +++ b/stdlib/os.go @@ -11,34 +11,34 @@ import ( ) var osModule = map[string]tengo.Object{ - "o_rdonly": &tengo.Int{Value: int64(os.O_RDONLY)}, - "o_wronly": &tengo.Int{Value: int64(os.O_WRONLY)}, - "o_rdwr": &tengo.Int{Value: int64(os.O_RDWR)}, - "o_append": &tengo.Int{Value: int64(os.O_APPEND)}, - "o_create": &tengo.Int{Value: int64(os.O_CREATE)}, - "o_excl": &tengo.Int{Value: int64(os.O_EXCL)}, - "o_sync": &tengo.Int{Value: int64(os.O_SYNC)}, - "o_trunc": &tengo.Int{Value: int64(os.O_TRUNC)}, - "mode_dir": &tengo.Int{Value: int64(os.ModeDir)}, - "mode_append": &tengo.Int{Value: int64(os.ModeAppend)}, - "mode_exclusive": &tengo.Int{Value: int64(os.ModeExclusive)}, - "mode_temporary": &tengo.Int{Value: int64(os.ModeTemporary)}, - "mode_symlink": &tengo.Int{Value: int64(os.ModeSymlink)}, - "mode_device": &tengo.Int{Value: int64(os.ModeDevice)}, - "mode_named_pipe": &tengo.Int{Value: int64(os.ModeNamedPipe)}, - "mode_socket": &tengo.Int{Value: int64(os.ModeSocket)}, - "mode_setuid": &tengo.Int{Value: int64(os.ModeSetuid)}, - "mode_setgui": &tengo.Int{Value: int64(os.ModeSetgid)}, - "mode_char_device": &tengo.Int{Value: int64(os.ModeCharDevice)}, - "mode_sticky": &tengo.Int{Value: int64(os.ModeSticky)}, - "mode_type": &tengo.Int{Value: int64(os.ModeType)}, - "mode_perm": &tengo.Int{Value: int64(os.ModePerm)}, - "path_separator": &tengo.Char{Value: os.PathSeparator}, - "path_list_separator": &tengo.Char{Value: os.PathListSeparator}, + "o_rdonly": tengo.Int{Value: int64(os.O_RDONLY)}, + "o_wronly": tengo.Int{Value: int64(os.O_WRONLY)}, + "o_rdwr": tengo.Int{Value: int64(os.O_RDWR)}, + "o_append": tengo.Int{Value: int64(os.O_APPEND)}, + "o_create": tengo.Int{Value: int64(os.O_CREATE)}, + "o_excl": tengo.Int{Value: int64(os.O_EXCL)}, + "o_sync": tengo.Int{Value: int64(os.O_SYNC)}, + "o_trunc": tengo.Int{Value: int64(os.O_TRUNC)}, + "mode_dir": tengo.Int{Value: int64(os.ModeDir)}, + "mode_append": tengo.Int{Value: int64(os.ModeAppend)}, + "mode_exclusive": tengo.Int{Value: int64(os.ModeExclusive)}, + "mode_temporary": tengo.Int{Value: int64(os.ModeTemporary)}, + "mode_symlink": tengo.Int{Value: int64(os.ModeSymlink)}, + "mode_device": tengo.Int{Value: int64(os.ModeDevice)}, + "mode_named_pipe": tengo.Int{Value: int64(os.ModeNamedPipe)}, + "mode_socket": tengo.Int{Value: int64(os.ModeSocket)}, + "mode_setuid": tengo.Int{Value: int64(os.ModeSetuid)}, + "mode_setgui": tengo.Int{Value: int64(os.ModeSetgid)}, + "mode_char_device": tengo.Int{Value: int64(os.ModeCharDevice)}, + "mode_sticky": tengo.Int{Value: int64(os.ModeSticky)}, + "mode_type": tengo.Int{Value: int64(os.ModeType)}, + "mode_perm": tengo.Int{Value: int64(os.ModePerm)}, + "path_separator": tengo.Char{Value: os.PathSeparator}, + "path_list_separator": tengo.Char{Value: os.PathListSeparator}, "dev_null": &tengo.String{Value: os.DevNull}, - "seek_set": &tengo.Int{Value: int64(io.SeekStart)}, - "seek_cur": &tengo.Int{Value: int64(io.SeekCurrent)}, - "seek_end": &tengo.Int{Value: int64(io.SeekEnd)}, + "seek_set": tengo.Int{Value: int64(io.SeekStart)}, + "seek_cur": tengo.Int{Value: int64(io.SeekCurrent)}, + "seek_end": tengo.Int{Value: int64(io.SeekEnd)}, "args": &tengo.UserFunction{ Name: "args", Value: osArgs, @@ -242,8 +242,8 @@ func osStat(args ...tengo.Object) (ret tengo.Object, err error) { Value: map[string]tengo.Object{ "name": &tengo.String{Value: stat.Name()}, "mtime": &tengo.Time{Value: stat.ModTime()}, - "size": &tengo.Int{Value: stat.Size()}, - "mode": &tengo.Int{Value: int64(stat.Mode())}, + "size": tengo.Int{Value: stat.Size()}, + "mode": tengo.Int{Value: int64(stat.Mode())}, }, } if stat.IsDir() { diff --git a/stdlib/os_file.go b/stdlib/os_file.go index 4f59b4c4..31b981ab 100644 --- a/stdlib/os_file.go +++ b/stdlib/os_file.go @@ -99,7 +99,7 @@ func makeOSFile(file *os.File) *tengo.ImmutableMap { if err != nil { return wrapError(err), nil } - return &tengo.Int{Value: res}, nil + return tengo.Int{Value: res}, nil }, }, // stat() => imap(fileinfo)/error diff --git a/stdlib/os_test.go b/stdlib/os_test.go index 46c7f601..a73a18fa 100644 --- a/stdlib/os_test.go +++ b/stdlib/os_test.go @@ -50,8 +50,8 @@ func TestFileStatFile(t *testing.T) { Value: map[string]tengo.Object{ "name": &tengo.String{Value: stat.Name()}, "mtime": &tengo.Time{Value: stat.ModTime()}, - "size": &tengo.Int{Value: stat.Size()}, - "mode": &tengo.Int{Value: int64(stat.Mode())}, + "size": tengo.Int{Value: stat.Size()}, + "mode": tengo.Int{Value: int64(stat.Mode())}, "directory": tengo.FalseValue, }, }) @@ -69,8 +69,8 @@ func TestFileStatDir(t *testing.T) { Value: map[string]tengo.Object{ "name": &tengo.String{Value: stat.Name()}, "mtime": &tengo.Time{Value: stat.ModTime()}, - "size": &tengo.Int{Value: stat.Size()}, - "mode": &tengo.Int{Value: int64(stat.Mode())}, + "size": tengo.Int{Value: stat.Size()}, + "mode": tengo.Int{Value: int64(stat.Mode())}, "directory": tengo.TrueValue, }, }) diff --git a/stdlib/rand.go b/stdlib/rand.go index 5d21e1df..8fb61f85 100644 --- a/stdlib/rand.go +++ b/stdlib/rand.go @@ -54,7 +54,7 @@ var randModule = map[string]tengo.Object{ ret = wrapError(err) return } - return &tengo.Int{Value: int64(res)}, nil + return tengo.Int{Value: int64(res)}, nil }, }, "rand": &tengo.UserFunction{ @@ -130,7 +130,7 @@ func randRand(r *rand.Rand) *tengo.ImmutableMap { ret = wrapError(err) return } - return &tengo.Int{Value: int64(res)}, nil + return tengo.Int{Value: int64(res)}, nil }, }, }, diff --git a/stdlib/stdlib_test.go b/stdlib/stdlib_test.go index ecd59788..0861892e 100644 --- a/stdlib/stdlib_test.go +++ b/stdlib/stdlib_test.go @@ -172,20 +172,20 @@ func object(v interface{}) tengo.Object { case string: return &tengo.String{Value: v} case int64: - return &tengo.Int{Value: v} + return tengo.Int{Value: v} case int: // for convenience - return &tengo.Int{Value: int64(v)} + return tengo.Int{Value: int64(v)} case bool: if v { return tengo.TrueValue } return tengo.FalseValue case rune: - return &tengo.Char{Value: v} + return tengo.Char{Value: v} case byte: // for convenience - return &tengo.Char{Value: rune(v)} + return tengo.Char{Value: rune(v)} case float64: - return &tengo.Float{Value: v} + return tengo.Float{Value: v} case []byte: return &tengo.Bytes{Value: v} case MAP: @@ -221,7 +221,7 @@ func object(v interface{}) tengo.Object { case []int: var objs []tengo.Object for _, e := range v { - objs = append(objs, &tengo.Int{Value: int64(e)}) + objs = append(objs, tengo.Int{Value: int64(e)}) } return &tengo.Array{Value: objs} diff --git a/stdlib/text.go b/stdlib/text.go index d7d5d1da..2c0565ac 100644 --- a/stdlib/text.go +++ b/stdlib/text.go @@ -287,8 +287,8 @@ func textREFind(args ...tengo.Object) (ret tengo.Object, err error) { arr.Value = append(arr.Value, &tengo.ImmutableMap{Value: map[string]tengo.Object{ "text": &tengo.String{Value: s2[m[i]:m[i+1]]}, - "begin": &tengo.Int{Value: int64(m[i])}, - "end": &tengo.Int{Value: int64(m[i+1])}, + "begin": tengo.Int{Value: int64(m[i])}, + "end": tengo.Int{Value: int64(m[i+1])}, }}) } @@ -319,8 +319,8 @@ func textREFind(args ...tengo.Object) (ret tengo.Object, err error) { subMatch.Value = append(subMatch.Value, &tengo.ImmutableMap{Value: map[string]tengo.Object{ "text": &tengo.String{Value: s2[m[i]:m[i+1]]}, - "begin": &tengo.Int{Value: int64(m[i])}, - "end": &tengo.Int{Value: int64(m[i+1])}, + "begin": tengo.Int{Value: int64(m[i])}, + "end": tengo.Int{Value: int64(m[i+1])}, }}) } @@ -831,7 +831,7 @@ func textFormatFloat(args ...tengo.Object) (ret tengo.Object, err error) { return } - f1, ok := args[0].(*tengo.Float) + f1, ok := args[0].(tengo.Float) if !ok { err = tengo.ErrInvalidArgumentType{ Name: "first", @@ -882,7 +882,7 @@ func textFormatInt(args ...tengo.Object) (ret tengo.Object, err error) { return } - i1, ok := args[0].(*tengo.Int) + i1, ok := args[0].(tengo.Int) if !ok { err = tengo.ErrInvalidArgumentType{ Name: "first", @@ -970,7 +970,7 @@ func textParseFloat(args ...tengo.Object) (ret tengo.Object, err error) { return } - ret = &tengo.Float{Value: parsed} + ret = tengo.Float{Value: parsed} return } @@ -1017,7 +1017,7 @@ func textParseInt(args ...tengo.Object) (ret tengo.Object, err error) { return } - ret = &tengo.Int{Value: parsed} + ret = tengo.Int{Value: parsed} return } diff --git a/stdlib/text_regexp.go b/stdlib/text_regexp.go index 1a7ecf07..94898c7e 100644 --- a/stdlib/text_regexp.go +++ b/stdlib/text_regexp.go @@ -78,10 +78,10 @@ func makeTextRegexp(re *regexp.Regexp) *tengo.ImmutableMap { "text": &tengo.String{ Value: s1[m[i]:m[i+1]], }, - "begin": &tengo.Int{ + "begin": tengo.Int{ Value: int64(m[i]), }, - "end": &tengo.Int{ + "end": tengo.Int{ Value: int64(m[i+1]), }, }}) @@ -117,10 +117,10 @@ func makeTextRegexp(re *regexp.Regexp) *tengo.ImmutableMap { "text": &tengo.String{ Value: s1[m[i]:m[i+1]], }, - "begin": &tengo.Int{ + "begin": tengo.Int{ Value: int64(m[i]), }, - "end": &tengo.Int{ + "end": tengo.Int{ Value: int64(m[i+1]), }, }}) diff --git a/stdlib/times.go b/stdlib/times.go index 0b6f7bd4..96c8aa10 100644 --- a/stdlib/times.go +++ b/stdlib/times.go @@ -22,24 +22,24 @@ var timesModule = map[string]tengo.Object{ "format_stamp_milli": &tengo.String{Value: time.StampMilli}, "format_stamp_micro": &tengo.String{Value: time.StampMicro}, "format_stamp_nano": &tengo.String{Value: time.StampNano}, - "nanosecond": &tengo.Int{Value: int64(time.Nanosecond)}, - "microsecond": &tengo.Int{Value: int64(time.Microsecond)}, - "millisecond": &tengo.Int{Value: int64(time.Millisecond)}, - "second": &tengo.Int{Value: int64(time.Second)}, - "minute": &tengo.Int{Value: int64(time.Minute)}, - "hour": &tengo.Int{Value: int64(time.Hour)}, - "january": &tengo.Int{Value: int64(time.January)}, - "february": &tengo.Int{Value: int64(time.February)}, - "march": &tengo.Int{Value: int64(time.March)}, - "april": &tengo.Int{Value: int64(time.April)}, - "may": &tengo.Int{Value: int64(time.May)}, - "june": &tengo.Int{Value: int64(time.June)}, - "july": &tengo.Int{Value: int64(time.July)}, - "august": &tengo.Int{Value: int64(time.August)}, - "september": &tengo.Int{Value: int64(time.September)}, - "october": &tengo.Int{Value: int64(time.October)}, - "november": &tengo.Int{Value: int64(time.November)}, - "december": &tengo.Int{Value: int64(time.December)}, + "nanosecond": tengo.Int{Value: int64(time.Nanosecond)}, + "microsecond": tengo.Int{Value: int64(time.Microsecond)}, + "millisecond": tengo.Int{Value: int64(time.Millisecond)}, + "second": tengo.Int{Value: int64(time.Second)}, + "minute": tengo.Int{Value: int64(time.Minute)}, + "hour": tengo.Int{Value: int64(time.Hour)}, + "january": tengo.Int{Value: int64(time.January)}, + "february": tengo.Int{Value: int64(time.February)}, + "march": tengo.Int{Value: int64(time.March)}, + "april": tengo.Int{Value: int64(time.April)}, + "may": tengo.Int{Value: int64(time.May)}, + "june": tengo.Int{Value: int64(time.June)}, + "july": tengo.Int{Value: int64(time.July)}, + "august": tengo.Int{Value: int64(time.August)}, + "september": tengo.Int{Value: int64(time.September)}, + "october": tengo.Int{Value: int64(time.October)}, + "november": tengo.Int{Value: int64(time.November)}, + "december": tengo.Int{Value: int64(time.December)}, "sleep": &tengo.UserFunction{ Name: "sleep", Value: timesSleep, @@ -229,7 +229,7 @@ func timesParseDuration(args ...tengo.Object) ( return } - ret = &tengo.Int{Value: int64(dur)} + ret = tengo.Int{Value: int64(dur)} return } @@ -253,7 +253,7 @@ func timesSince(args ...tengo.Object) ( return } - ret = &tengo.Int{Value: int64(time.Since(t1))} + ret = tengo.Int{Value: int64(time.Since(t1))} return } @@ -277,7 +277,7 @@ func timesUntil(args ...tengo.Object) ( return } - ret = &tengo.Int{Value: int64(time.Until(t1))} + ret = tengo.Int{Value: int64(time.Until(t1))} return } @@ -301,7 +301,7 @@ func timesDurationHours(args ...tengo.Object) ( return } - ret = &tengo.Float{Value: time.Duration(i1).Hours()} + ret = tengo.Float{Value: time.Duration(i1).Hours()} return } @@ -325,7 +325,7 @@ func timesDurationMinutes(args ...tengo.Object) ( return } - ret = &tengo.Float{Value: time.Duration(i1).Minutes()} + ret = tengo.Float{Value: time.Duration(i1).Minutes()} return } @@ -349,7 +349,7 @@ func timesDurationNanoseconds(args ...tengo.Object) ( return } - ret = &tengo.Int{Value: time.Duration(i1).Nanoseconds()} + ret = tengo.Int{Value: time.Duration(i1).Nanoseconds()} return } @@ -373,7 +373,7 @@ func timesDurationSeconds(args ...tengo.Object) ( return } - ret = &tengo.Float{Value: time.Duration(i1).Seconds()} + ret = tengo.Float{Value: time.Duration(i1).Seconds()} return } @@ -643,7 +643,7 @@ func timesSub(args ...tengo.Object) (ret tengo.Object, err error) { return } - ret = &tengo.Int{Value: int64(t1.Sub(t2))} + ret = tengo.Int{Value: int64(t1.Sub(t2))} return } @@ -785,7 +785,7 @@ func timesTimeYear(args ...tengo.Object) (ret tengo.Object, err error) { return } - ret = &tengo.Int{Value: int64(t1.Year())} + ret = tengo.Int{Value: int64(t1.Year())} return } @@ -806,7 +806,7 @@ func timesTimeMonth(args ...tengo.Object) (ret tengo.Object, err error) { return } - ret = &tengo.Int{Value: int64(t1.Month())} + ret = tengo.Int{Value: int64(t1.Month())} return } @@ -827,7 +827,7 @@ func timesTimeDay(args ...tengo.Object) (ret tengo.Object, err error) { return } - ret = &tengo.Int{Value: int64(t1.Day())} + ret = tengo.Int{Value: int64(t1.Day())} return } @@ -848,7 +848,7 @@ func timesTimeWeekday(args ...tengo.Object) (ret tengo.Object, err error) { return } - ret = &tengo.Int{Value: int64(t1.Weekday())} + ret = tengo.Int{Value: int64(t1.Weekday())} return } @@ -869,7 +869,7 @@ func timesTimeHour(args ...tengo.Object) (ret tengo.Object, err error) { return } - ret = &tengo.Int{Value: int64(t1.Hour())} + ret = tengo.Int{Value: int64(t1.Hour())} return } @@ -890,7 +890,7 @@ func timesTimeMinute(args ...tengo.Object) (ret tengo.Object, err error) { return } - ret = &tengo.Int{Value: int64(t1.Minute())} + ret = tengo.Int{Value: int64(t1.Minute())} return } @@ -911,7 +911,7 @@ func timesTimeSecond(args ...tengo.Object) (ret tengo.Object, err error) { return } - ret = &tengo.Int{Value: int64(t1.Second())} + ret = tengo.Int{Value: int64(t1.Second())} return } @@ -935,7 +935,7 @@ func timesTimeNanosecond(args ...tengo.Object) ( return } - ret = &tengo.Int{Value: int64(t1.Nanosecond())} + ret = tengo.Int{Value: int64(t1.Nanosecond())} return } @@ -956,7 +956,7 @@ func timesTimeUnix(args ...tengo.Object) (ret tengo.Object, err error) { return } - ret = &tengo.Int{Value: t1.Unix()} + ret = tengo.Int{Value: t1.Unix()} return } @@ -980,7 +980,7 @@ func timesTimeUnixNano(args ...tengo.Object) ( return } - ret = &tengo.Int{Value: t1.UnixNano()} + ret = tengo.Int{Value: t1.UnixNano()} return } diff --git a/stdlib/times_test.go b/stdlib/times_test.go index 6977ba46..07881730 100644 --- a/stdlib/times_test.go +++ b/stdlib/times_test.go @@ -16,10 +16,10 @@ func TestTimes(t *testing.T) { require.True(t, module(t, "times"). call("since", time.Now().Add(-time.Hour)). - o.(*tengo.Int).Value > 3600000000000) + o.(tengo.Int).Value > 3600000000000) require.True(t, module(t, "times"). call("until", time.Now().Add(time.Hour)). - o.(*tengo.Int).Value < 3600000000000) + o.(tengo.Int).Value < 3600000000000) module(t, "times").call("parse_duration", "1ns").expect(1) module(t, "times").call("parse_duration", "1ms").expect(1000000) diff --git a/tengo.go b/tengo.go index 490e9aed..1640bdd3 100644 --- a/tengo.go +++ b/tengo.go @@ -79,13 +79,13 @@ func ToString(o Object) (v string, ok bool) { // ToInt will try to convert object o to int value. func ToInt(o Object) (v int, ok bool) { switch o := o.(type) { - case *Int: + case Int: v = int(o.Value) ok = true - case *Float: + case Float: v = int(o.Value) ok = true - case *Char: + case Char: v = int(o.Value) ok = true case *Bool: @@ -106,13 +106,13 @@ func ToInt(o Object) (v int, ok bool) { // ToInt64 will try to convert object o to int64 value. func ToInt64(o Object) (v int64, ok bool) { switch o := o.(type) { - case *Int: + case Int: v = o.Value ok = true - case *Float: + case Float: v = int64(o.Value) ok = true - case *Char: + case Char: v = int64(o.Value) ok = true case *Bool: @@ -133,10 +133,10 @@ func ToInt64(o Object) (v int64, ok bool) { // ToFloat64 will try to convert object o to float64 value. func ToFloat64(o Object) (v float64, ok bool) { switch o := o.(type) { - case *Int: + case Int: v = float64(o.Value) ok = true - case *Float: + case Float: v = o.Value ok = true case *String: @@ -159,10 +159,10 @@ func ToBool(o Object) (v bool, ok bool) { // ToRune will try to convert object o to rune value. func ToRune(o Object) (v rune, ok bool) { switch o := o.(type) { - case *Int: + case Int: v = rune(o.Value) ok = true - case *Char: + case Char: v = o.Value ok = true } @@ -188,7 +188,7 @@ func ToTime(o Object) (v time.Time, ok bool) { case *Time: v = o.Value ok = true - case *Int: + case Int: v = time.Unix(o.Value, 0) ok = true } @@ -198,15 +198,15 @@ func ToTime(o Object) (v time.Time, ok bool) { // ToInterface attempts to convert an object o to an interface{} value func ToInterface(o Object) (res interface{}) { switch o := o.(type) { - case *Int: + case Int: res = o.Value case *String: res = o.Value - case *Float: + case Float: res = o.Value case *Bool: res = o == TrueValue - case *Char: + case Char: res = o.Value case *Bytes: res = o.Value @@ -253,20 +253,20 @@ func FromInterface(v interface{}) (Object, error) { } return &String{Value: v}, nil case int64: - return &Int{Value: v}, nil + return Int{Value: v}, nil case int: - return &Int{Value: int64(v)}, nil + return Int{Value: int64(v)}, nil case bool: if v { return TrueValue, nil } return FalseValue, nil case rune: - return &Char{Value: v}, nil + return Char{Value: v}, nil case byte: - return &Char{Value: rune(v)}, nil + return Char{Value: rune(v)}, nil case float64: - return &Float{Value: v}, nil + return Float{Value: v}, nil case []byte: if len(v) > MaxBytesLen { return nil, ErrBytesLimit diff --git a/tengo_test.go b/tengo_test.go index d1f5e8ac..0f2e98cc 100644 --- a/tengo_test.go +++ b/tengo_test.go @@ -59,49 +59,49 @@ func TestMakeInstruction(t *testing.T) { func TestNumObjects(t *testing.T) { testCountObjects(t, &tengo.Array{}, 1) testCountObjects(t, &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}, &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 3}, - &tengo.Int{Value: 4}, - &tengo.Int{Value: 5}, + tengo.Int{Value: 3}, + tengo.Int{Value: 4}, + tengo.Int{Value: 5}, }}, }}, 7) testCountObjects(t, tengo.TrueValue, 1) testCountObjects(t, tengo.FalseValue, 1) testCountObjects(t, &tengo.BuiltinFunction{}, 1) testCountObjects(t, &tengo.Bytes{Value: []byte("foobar")}, 1) - testCountObjects(t, &tengo.Char{Value: '가'}, 1) + testCountObjects(t, tengo.Char{Value: '가'}, 1) testCountObjects(t, &tengo.CompiledFunction{}, 1) - testCountObjects(t, &tengo.Error{Value: &tengo.Int{Value: 5}}, 2) - testCountObjects(t, &tengo.Float{Value: 19.84}, 1) + testCountObjects(t, &tengo.Error{Value: tengo.Int{Value: 5}}, 2) + testCountObjects(t, tengo.Float{Value: 19.84}, 1) testCountObjects(t, &tengo.ImmutableArray{Value: []tengo.Object{ - &tengo.Int{Value: 1}, - &tengo.Int{Value: 2}, + tengo.Int{Value: 1}, + tengo.Int{Value: 2}, &tengo.ImmutableArray{Value: []tengo.Object{ - &tengo.Int{Value: 3}, - &tengo.Int{Value: 4}, - &tengo.Int{Value: 5}, + tengo.Int{Value: 3}, + tengo.Int{Value: 4}, + tengo.Int{Value: 5}, }}, }}, 7) testCountObjects(t, &tengo.ImmutableMap{ Value: map[string]tengo.Object{ - "k1": &tengo.Int{Value: 1}, - "k2": &tengo.Int{Value: 2}, + "k1": tengo.Int{Value: 1}, + "k2": tengo.Int{Value: 2}, "k3": &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 3}, - &tengo.Int{Value: 4}, - &tengo.Int{Value: 5}, + tengo.Int{Value: 3}, + tengo.Int{Value: 4}, + tengo.Int{Value: 5}, }}, }}, 7) - testCountObjects(t, &tengo.Int{Value: 1984}, 1) + testCountObjects(t, tengo.Int{Value: 1984}, 1) testCountObjects(t, &tengo.Map{Value: map[string]tengo.Object{ - "k1": &tengo.Int{Value: 1}, - "k2": &tengo.Int{Value: 2}, + "k1": tengo.Int{Value: 1}, + "k2": tengo.Int{Value: 2}, "k3": &tengo.Array{Value: []tengo.Object{ - &tengo.Int{Value: 3}, - &tengo.Int{Value: 4}, - &tengo.Int{Value: 5}, + tengo.Int{Value: 3}, + tengo.Int{Value: 4}, + tengo.Int{Value: 5}, }}, }}, 7) testCountObjects(t, &tengo.String{Value: "foo bar"}, 1) diff --git a/variable_test.go b/variable_test.go index f39c9c9e..4d5e8d5d 100644 --- a/variable_test.go +++ b/variable_test.go @@ -33,7 +33,7 @@ func TestVariable(t *testing.T) { CharValue: rune(1), BoolValue: true, StringValue: "1", - Object: &tengo.Int{Value: 1}, + Object: tengo.Int{Value: 1}, }, { Name: "b", diff --git a/vm.go b/vm.go index c8365252..a10173f0 100644 --- a/vm.go +++ b/vm.go @@ -175,8 +175,8 @@ func (v *VM) run() { v.sp-- switch x := operand.(type) { - case *Int: - var res Object = &Int{Value: ^x.Value} + case Int: + var res Object = Int{Value: ^x.Value} v.allocs-- if v.allocs == 0 { v.err = ErrObjectAllocLimit @@ -194,8 +194,8 @@ func (v *VM) run() { v.sp-- switch x := operand.(type) { - case *Int: - var res Object = &Int{Value: -x.Value} + case Int: + var res Object = Int{Value: -x.Value} v.allocs-- if v.allocs == 0 { v.err = ErrObjectAllocLimit @@ -203,8 +203,8 @@ func (v *VM) run() { } v.stack[v.sp] = res v.sp++ - case *Float: - var res Object = &Float{Value: -x.Value} + case Float: + var res Object = Float{Value: -x.Value} v.allocs-- if v.allocs == 0 { v.err = ErrObjectAllocLimit @@ -275,7 +275,7 @@ func (v *VM) run() { v.ip += 2 numElements := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8 - var elements []Object + elements := make([]Object, 0, numElements) for i := v.sp - numElements; i < v.sp; i++ { elements = append(elements, v.stack[i]) } @@ -376,7 +376,7 @@ func (v *VM) run() { var lowIdx int64 if low != UndefinedValue { - if low, ok := low.(*Int); ok { + if low, ok := low.(Int); ok { lowIdx = low.Value } else { v.err = fmt.Errorf("invalid slice index type: %s", @@ -391,7 +391,7 @@ func (v *VM) run() { var highIdx int64 if high == UndefinedValue { highIdx = numElements - } else if high, ok := high.(*Int); ok { + } else if high, ok := high.(Int); ok { highIdx = high.Value } else { v.err = fmt.Errorf("invalid slice index type: %s", @@ -428,7 +428,7 @@ func (v *VM) run() { var highIdx int64 if high == UndefinedValue { highIdx = numElements - } else if high, ok := high.(*Int); ok { + } else if high, ok := high.(Int); ok { highIdx = high.Value } else { v.err = fmt.Errorf("invalid slice index type: %s", @@ -465,7 +465,7 @@ func (v *VM) run() { var highIdx int64 if high == UndefinedValue { highIdx = numElements - } else if high, ok := high.(*Int); ok { + } else if high, ok := high.(Int); ok { highIdx = high.Value } else { v.err = fmt.Errorf("invalid slice index type: %s", @@ -502,7 +502,7 @@ func (v *VM) run() { var highIdx int64 if high == UndefinedValue { highIdx = numElements - } else if high, ok := high.(*Int); ok { + } else if high, ok := high.(Int); ok { highIdx = high.Value } else { v.err = fmt.Errorf("invalid slice index type: %s", @@ -628,8 +628,7 @@ func (v *VM) run() { v.framesIndex++ v.sp = v.sp - numArgs + callee.NumLocals } else { - var args []Object - args = append(args, v.stack[v.sp-numArgs:v.sp]...) + args := v.stack[v.sp-numArgs : v.sp] ret, e := value.Call(args...) v.sp -= numArgs + 1 diff --git a/vm_test.go b/vm_test.go index feb91f4f..15d996d9 100644 --- a/vm_test.go +++ b/vm_test.go @@ -5,7 +5,6 @@ import ( "fmt" "math" "math/rand" - "reflect" _runtime "runtime" "strings" "testing" @@ -2094,7 +2093,7 @@ func TestIncDec(t *testing.T) { } type StringDict struct { - tengo.ObjectImpl + tengo.PtrObjectImpl Value map[string]string } @@ -2136,7 +2135,7 @@ func (o *StringDict) IndexSet(index, value tengo.Object) error { } type StringCircle struct { - tengo.ObjectImpl + tengo.PtrObjectImpl Value []string } @@ -2149,7 +2148,7 @@ func (o *StringCircle) String() string { } func (o *StringCircle) IndexGet(index tengo.Object) (tengo.Object, error) { - intIdx, ok := index.(*tengo.Int) + intIdx, ok := index.(tengo.Int) if !ok { return nil, tengo.ErrInvalidIndexType } @@ -2163,7 +2162,7 @@ func (o *StringCircle) IndexGet(index tengo.Object) (tengo.Object, error) { } func (o *StringCircle) IndexSet(index, value tengo.Object) error { - intIdx, ok := index.(*tengo.Int) + intIdx, ok := index.(tengo.Int) if !ok { return tengo.ErrInvalidIndexType } @@ -2184,7 +2183,7 @@ func (o *StringCircle) IndexSet(index, value tengo.Object) error { } type StringArray struct { - tengo.ObjectImpl + tengo.PtrObjectImpl Value []string } @@ -2242,7 +2241,7 @@ func (o *StringArray) TypeName() string { } func (o *StringArray) IndexGet(index tengo.Object) (tengo.Object, error) { - intIdx, ok := index.(*tengo.Int) + intIdx, ok := index.(tengo.Int) if ok { if intIdx.Value >= 0 && intIdx.Value < int64(len(o.Value)) { return &tengo.String{Value: o.Value[intIdx.Value]}, nil @@ -2255,7 +2254,7 @@ func (o *StringArray) IndexGet(index tengo.Object) (tengo.Object, error) { if ok { for vidx, str := range o.Value { if strIdx.Value == str { - return &tengo.Int{Value: int64(vidx)}, nil + return tengo.Int{Value: int64(vidx)}, nil } } @@ -2271,7 +2270,7 @@ func (o *StringArray) IndexSet(index, value tengo.Object) error { return tengo.ErrInvalidIndexValueType } - intIdx, ok := index.(*tengo.Int) + intIdx, ok := index.(tengo.Int) if ok { if intIdx.Value >= 0 && intIdx.Value < int64(len(o.Value)) { o.Value[intIdx.Value] = strVal @@ -2302,7 +2301,7 @@ func (o *StringArray) Call( for i, v := range o.Value { if v == s1 { - return &tengo.Int{Value: int64(i)}, nil + return tengo.Int{Value: int64(i)}, nil } } @@ -2423,7 +2422,7 @@ func TestInteger(t *testing.T) { } type StringArrayIterator struct { - tengo.ObjectImpl + tengo.PtrObjectImpl strArr *StringArray idx int } @@ -2442,7 +2441,7 @@ func (i *StringArrayIterator) Next() bool { } func (i *StringArrayIterator) Key() tengo.Object { - return &tengo.Int{Value: int64(i.idx - 1)} + return tengo.Int{Value: int64(i.idx - 1)} } func (i *StringArrayIterator) Value() tengo.Object { @@ -2573,7 +2572,7 @@ func TestBuiltin(t *testing.T) { Name: "abs", Value: func(a ...tengo.Object) (tengo.Object, error) { v, _ := tengo.ToFloat64(a[0]) - return &tengo.Float{Value: math.Abs(v)}, nil + return tengo.Float{Value: math.Abs(v)}, nil }, }, }, @@ -2779,7 +2778,7 @@ func TestModuleBlockScopes(t *testing.T) { Name: "abs", Value: func(a ...tengo.Object) (tengo.Object, error) { v, _ := tengo.ToInt64(a[0]) - return &tengo.Int{Value: rand.Int63n(v)}, nil + return tengo.Int{Value: rand.Int63n(v)}, nil }, }, }, @@ -3873,7 +3872,7 @@ func formatGlobals(globals []tengo.Object) (formatted []string) { return } formatted = append(formatted, fmt.Sprintf("[% 3d] %s (%s|%p)", - idx, global.String(), reflect.TypeOf(global).Elem().Name(), global)) + idx, global.String(), global.TypeName(), global)) } return } @@ -3899,20 +3898,20 @@ func toObject(v interface{}) tengo.Object { case string: return &tengo.String{Value: v} case int64: - return &tengo.Int{Value: v} + return tengo.Int{Value: v} case int: // for convenience - return &tengo.Int{Value: int64(v)} + return tengo.Int{Value: int64(v)} case bool: if v { return tengo.TrueValue } return tengo.FalseValue case rune: - return &tengo.Char{Value: v} + return tengo.Char{Value: v} case byte: // for convenience - return &tengo.Char{Value: rune(v)} + return tengo.Char{Value: rune(v)} case float64: - return &tengo.Float{Value: v} + return tengo.Float{Value: v} case []byte: return &tengo.Bytes{Value: v} case MAP: @@ -3950,14 +3949,14 @@ func toObject(v interface{}) tengo.Object { func objectZeroCopy(o tengo.Object) tengo.Object { switch o.(type) { - case *tengo.Int: - return &tengo.Int{} - case *tengo.Float: - return &tengo.Float{} + case tengo.Int: + return tengo.Int{} + case tengo.Float: + return tengo.Float{} case *tengo.Bool: return &tengo.Bool{} - case *tengo.Char: - return &tengo.Char{} + case tengo.Char: + return tengo.Char{} case *tengo.String: return &tengo.String{} case *tengo.Array: From 9515d2f2c0dc5891af976034506a9596ed1b91c0 Mon Sep 17 00:00:00 2001 From: E Sequeira Date: Wed, 20 Jul 2022 10:15:06 +0100 Subject: [PATCH 2/3] fix comment --- objects.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/objects.go b/objects.go index 4a2a0e9d..57c7ee1c 100644 --- a/objects.go +++ b/objects.go @@ -79,8 +79,8 @@ type Object interface { CanCall() bool } -// PtrObjectImpl represents a default Object Implementation. To defined a new -// value type, one can embed PtrObjectImpl in their type declarations to avoid +// ObjectImpl represents a default Object Implementation. To defined a new +// value type, one can embed ObjectImpl in their type declarations to avoid // implementing all non-significant methods. TypeName() and String() methods // still need to be implemented. type ObjectImpl struct { @@ -148,7 +148,7 @@ func (o ObjectImpl) CanCall() bool { return false } -// PtrObjectImpl represents a default Object Implementation. To defined a new +// PtrObjectImpl represents a default Object Implementation. To defined a new // value type, one can embed PtrObjectImpl in their type declarations to avoid // implementing all non-significant methods. TypeName() and String() methods // still need to be implemented. From fe792a9369a0cbc67f5ef73213edabc58b68e0de Mon Sep 17 00:00:00 2001 From: E Sequeira Date: Wed, 20 Jul 2022 16:20:02 +0100 Subject: [PATCH 3/3] value semantics for bools --- builtins.go | 4 ++-- bytecode.go | 4 ++-- formatter.go | 2 +- objects.go | 18 +++++++++--------- objects_test.go | 4 ++-- require/require.go | 2 +- stdlib/json/encode.go | 2 +- stdlib/text.go | 2 +- tengo.go | 6 +++--- vm_test.go | 4 ++-- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/builtins.go b/builtins.go index 8812671c..095de4b7 100644 --- a/builtins.go +++ b/builtins.go @@ -173,7 +173,7 @@ func builtinIsBool(args ...Object) (Object, error) { if len(args) != 1 { return nil, ErrWrongNumArguments } - if _, ok := args[0].(*Bool); ok { + if _, ok := args[0].(Bool); ok { return TrueValue, nil } return FalseValue, nil @@ -481,7 +481,7 @@ func builtinBool(args ...Object) (Object, error) { if len(args) != 1 { return nil, ErrWrongNumArguments } - if _, ok := args[0].(*Bool); ok { + if _, ok := args[0].(Bool); ok { return args[0], nil } v, ok := ToBool(args[0]) diff --git a/bytecode.go b/bytecode.go index b63c9507..02ae5657 100644 --- a/bytecode.go +++ b/bytecode.go @@ -187,7 +187,7 @@ func fixDecodedObject( modules *ModuleMap, ) (Object, error) { switch o := o.(type) { - case *Bool: + case Bool: if o.IsFalsy() { return FalseValue, nil } @@ -280,7 +280,7 @@ func init() { gob.Register(&parser.SourceFileSet{}) gob.Register(&parser.SourceFile{}) gob.Register(&Array{}) - gob.Register(&Bool{}) + gob.Register(Bool{}) gob.Register(&Bytes{}) gob.Register(Char{}) gob.Register(&CompiledFunction{}) diff --git a/formatter.go b/formatter.go index 3ec63546..5a823b0b 100644 --- a/formatter.go +++ b/formatter.go @@ -951,7 +951,7 @@ func (p *pp) printArg(arg Object, verb rune) { // Some types can be done without reflection. switch f := arg.(type) { - case *Bool: + case Bool: p.fmtBool(!f.IsFalsy(), verb) case Float: p.fmtFloat(f.Value, 64, verb) diff --git a/objects.go b/objects.go index 57c7ee1c..32fd4a09 100644 --- a/objects.go +++ b/objects.go @@ -14,10 +14,10 @@ import ( var ( // TrueValue represents a true value. - TrueValue Object = &Bool{value: true} + TrueValue Object = Bool{value: true} // FalseValue represents a false value. - FalseValue Object = &Bool{value: false} + FalseValue Object = Bool{value: false} // UndefinedValue represents an undefined value. UndefinedValue Object = &Undefined{} @@ -334,14 +334,14 @@ func (o *Array) CanIterate() bool { // Bool represents a boolean value. type Bool struct { - PtrObjectImpl + ObjectImpl // this is intentionally non-public to force using objects.TrueValue and // FalseValue always value bool } -func (o *Bool) String() string { +func (o Bool) String() string { if o.value { return "true" } @@ -350,23 +350,23 @@ func (o *Bool) String() string { } // TypeName returns the name of the type. -func (o *Bool) TypeName() string { +func (o Bool) TypeName() string { return "bool" } // Copy returns a copy of the type. -func (o *Bool) Copy() Object { +func (o Bool) Copy() Object { return o } // IsFalsy returns true if the value of the type is falsy. -func (o *Bool) IsFalsy() bool { +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 { +func (o Bool) Equals(x Object) bool { return o == x } @@ -377,7 +377,7 @@ func (o *Bool) GobDecode(b []byte) (err error) { } // GobEncode encodes bool values into bytes. -func (o *Bool) GobEncode() (b []byte, err error) { +func (o Bool) GobEncode() (b []byte, err error) { if o.value { b = []byte{1} } else { diff --git a/objects_test.go b/objects_test.go index c7c3470a..f86d46cf 100644 --- a/objects_test.go +++ b/objects_test.go @@ -17,7 +17,7 @@ func TestObject_TypeName(t *testing.T) { require.Equal(t, "char", o.TypeName()) o = &tengo.String{} require.Equal(t, "string", o.TypeName()) - o = &tengo.Bool{} + o = tengo.Bool{} require.Equal(t, "bool", o.TypeName()) o = &tengo.Array{} require.Equal(t, "array", o.TypeName()) @@ -131,7 +131,7 @@ func TestObject_BinaryOp(t *testing.T) { var o tengo.Object = tengo.Char{} _, err := o.BinaryOp(token.Add, tengo.UndefinedValue) require.Error(t, err) - o = &tengo.Bool{} + o = tengo.Bool{} _, err = o.BinaryOp(token.Add, tengo.UndefinedValue) require.Error(t, err) o = &tengo.Map{} diff --git a/require/require.go b/require/require.go index ea3835c9..e0460922 100644 --- a/require/require.go +++ b/require/require.go @@ -142,7 +142,7 @@ func Equal( Equal(t, expected.Value, actual.(*tengo.String).Value, msg...) case tengo.Char: Equal(t, expected.Value, actual.(tengo.Char).Value, msg...) - case *tengo.Bool: + case tengo.Bool: if expected != actual { failExpectedActual(t, expected, actual, msg...) } diff --git a/stdlib/json/encode.go b/stdlib/json/encode.go index 8f00318b..4077a4fb 100644 --- a/stdlib/json/encode.go +++ b/stdlib/json/encode.go @@ -193,7 +193,7 @@ func Encode(o tengo.Object) ([]byte, error) { idx++ } b = append(b, '}') - case *tengo.Bool: + case tengo.Bool: if o.IsFalsy() { b = strconv.AppendBool(b, false) } else { diff --git a/stdlib/text.go b/stdlib/text.go index 2c0565ac..baa733e6 100644 --- a/stdlib/text.go +++ b/stdlib/text.go @@ -806,7 +806,7 @@ func textFormatBool(args ...tengo.Object) (ret tengo.Object, err error) { return } - b1, ok := args[0].(*tengo.Bool) + b1, ok := args[0].(tengo.Bool) if !ok { err = tengo.ErrInvalidArgumentType{ Name: "first", diff --git a/tengo.go b/tengo.go index 1640bdd3..0f216bcb 100644 --- a/tengo.go +++ b/tengo.go @@ -88,7 +88,7 @@ func ToInt(o Object) (v int, ok bool) { case Char: v = int(o.Value) ok = true - case *Bool: + case Bool: if o == TrueValue { v = 1 } @@ -115,7 +115,7 @@ func ToInt64(o Object) (v int64, ok bool) { case Char: v = int64(o.Value) ok = true - case *Bool: + case Bool: if o == TrueValue { v = 1 } @@ -204,7 +204,7 @@ func ToInterface(o Object) (res interface{}) { res = o.Value case Float: res = o.Value - case *Bool: + case Bool: res = o == TrueValue case Char: res = o.Value diff --git a/vm_test.go b/vm_test.go index 15d996d9..6966dd44 100644 --- a/vm_test.go +++ b/vm_test.go @@ -3953,8 +3953,8 @@ func objectZeroCopy(o tengo.Object) tengo.Object { return tengo.Int{} case tengo.Float: return tengo.Float{} - case *tengo.Bool: - return &tengo.Bool{} + case tengo.Bool: + return tengo.Bool{} case tengo.Char: return tengo.Char{} case *tengo.String: