diff --git a/objects/builtin_convert.go b/objects/builtin_convert.go index 922efc0d..460a9213 100644 --- a/objects/builtin_convert.go +++ b/objects/builtin_convert.go @@ -1,7 +1,8 @@ package objects func builtinString(args ...Object) (Object, error) { - if len(args) != 1 { + argsLen := len(args) + if !(argsLen == 1 || argsLen == 2) { return nil, ErrWrongNumArguments } @@ -14,11 +15,18 @@ func builtinString(args ...Object) (Object, error) { return &String{Value: v}, nil } + if argsLen == 2 { + if _, ok := args[1].(*String); ok { + return args[1], nil + } + } + return UndefinedValue, nil } func builtinInt(args ...Object) (Object, error) { - if len(args) != 1 { + argsLen := len(args) + if !(argsLen == 1 || argsLen == 2) { return nil, ErrWrongNumArguments } @@ -31,11 +39,18 @@ func builtinInt(args ...Object) (Object, error) { return &Int{Value: v}, nil } + if argsLen == 2 { + if _, ok := args[1].(*Int); ok { + return args[1], nil + } + } + return UndefinedValue, nil } func builtinFloat(args ...Object) (Object, error) { - if len(args) != 1 { + argsLen := len(args) + if !(argsLen == 1 || argsLen == 2) { return nil, ErrWrongNumArguments } @@ -48,6 +63,15 @@ func builtinFloat(args ...Object) (Object, error) { return &Float{Value: v}, nil } + if argsLen == 2 { + if _, ok := args[1].(*Float); ok { + return args[1], nil + } else if _, ok := args[1].(*Int); ok { + v, _ := ToFloat64(args[1]) + return &Float{Value: v}, nil + } + } + return UndefinedValue, nil } @@ -69,7 +93,8 @@ func builtinBool(args ...Object) (Object, error) { } func builtinChar(args ...Object) (Object, error) { - if len(args) != 1 { + argsLen := len(args) + if !(argsLen == 1 || argsLen == 2) { return nil, ErrWrongNumArguments } @@ -82,11 +107,18 @@ func builtinChar(args ...Object) (Object, error) { return &Char{Value: v}, nil } + if argsLen == 2 { + if _, ok := args[1].(*Char); ok { + return args[1], nil + } + } + return UndefinedValue, nil } func builtinBytes(args ...Object) (Object, error) { - if len(args) != 1 { + argsLen := len(args) + if !(argsLen == 1 || argsLen == 2) { return nil, ErrWrongNumArguments } @@ -100,5 +132,17 @@ func builtinBytes(args ...Object) (Object, error) { return &Bytes{Value: v}, nil } + if argsLen == 2 { + // bytes(N) => create a new bytes with given size N + if n, ok := args[1].(*Int); ok { + return &Bytes{Value: make([]byte, int(n.Value))}, nil + } + + v, ok = ToByteSlice(args[1]) + if ok { + return &Bytes{Value: v}, nil + } + } + return UndefinedValue, nil } diff --git a/runtime/vm_builtin_test.go b/runtime/vm_builtin_test.go index 71746bb9..705834d4 100644 --- a/runtime/vm_builtin_test.go +++ b/runtime/vm_builtin_test.go @@ -27,6 +27,10 @@ func TestBuiltinFunction(t *testing.T) { expect(t, `out = int([1])`, undefined()) expect(t, `out = int({a: 1})`, undefined()) expect(t, `out = int(undefined)`, undefined()) + expect(t, `out = int("-522", 1)`, -522) + expect(t, `out = int(undefined, 1)`, 1) + expect(t, `out = int(undefined, 1.8)`, undefined()) + expect(t, `out = int(undefined, undefined)`, undefined()) expect(t, `out = string(1)`, "1") expect(t, `out = string(1.8)`, "1.8") @@ -37,6 +41,8 @@ func TestBuiltinFunction(t *testing.T) { expect(t, `out = string([1,8.1,true,3])`, "[1, 8.1, true, 3]") expect(t, `out = string({b: "foo"})`, `{b: "foo"}`) expect(t, `out = string(undefined)`, undefined()) // not "undefined" + expect(t, `out = string(1, "-522")`, "1") + expect(t, `out = string(undefined, "-522")`, "-522") // not "undefined" expect(t, `out = float(1)`, 1.0) expect(t, `out = float(1.8)`, 1.8) @@ -47,6 +53,11 @@ func TestBuiltinFunction(t *testing.T) { expect(t, `out = float([1,8.1,true,3])`, undefined()) expect(t, `out = float({a: 1, b: "foo"})`, undefined()) expect(t, `out = float(undefined)`, undefined()) + expect(t, `out = float("-52.2", 1.8)`, -52.2) + expect(t, `out = float(undefined, 1)`, 1.0) + expect(t, `out = float(undefined, 1.8)`, 1.8) + expect(t, `out = float(undefined, "-52.2")`, undefined()) + expect(t, `out = float(undefined, undefined)`, undefined()) expect(t, `out = char(56)`, '8') expect(t, `out = char(1.8)`, undefined()) @@ -57,6 +68,10 @@ func TestBuiltinFunction(t *testing.T) { expect(t, `out = char([1,8.1,true,3])`, undefined()) expect(t, `out = char({a: 1, b: "foo"})`, undefined()) expect(t, `out = char(undefined)`, undefined()) + expect(t, `out = char(56, 'a')`, '8') + expect(t, `out = char(undefined, '8')`, '8') + expect(t, `out = char(undefined, 56)`, undefined()) + expect(t, `out = char(undefined, "-52.2")`, undefined()) expect(t, `out = bool(1)`, true) // non-zero integer: true expect(t, `out = bool(0)`, false) // zero: true @@ -83,6 +98,11 @@ func TestBuiltinFunction(t *testing.T) { expect(t, `out = bytes([1])`, undefined()) expect(t, `out = bytes({a: 1})`, undefined()) expect(t, `out = bytes(undefined)`, undefined()) + expect(t, `out = bytes("-522", ['8'])`, []byte{'-', '5', '2', '2'}) + expect(t, `out = bytes(undefined, "-522")`, []byte{'-', '5', '2', '2'}) + expect(t, `out = bytes(undefined, 1)`, []byte{0}) + expect(t, `out = bytes(undefined, 1.8)`, undefined()) + expect(t, `out = bytes(undefined, undefined)`, undefined()) expect(t, `out = is_error(error(1))`, true) expect(t, `out = is_error(1)`, false)