Skip to content

Commit

Permalink
Builtin converts now take default values
Browse files Browse the repository at this point in the history
objects/builtin_convert.go: Added defaults to all builtin convert functions except
bool as this one returns false for undefined, instead of undefined.

runtime/vm_builtin_test.go: Added tests for checking default value
behaviour for builtin convert funcs
  • Loading branch information
Mike Bazuin committed Jan 18, 2019
1 parent b4a2da8 commit a747c98
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 5 deletions.
54 changes: 49 additions & 5 deletions 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
}

Expand All @@ -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
}

Expand All @@ -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
}

Expand All @@ -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
}

Expand All @@ -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
}

Expand All @@ -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
}

Expand All @@ -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
}
20 changes: 20 additions & 0 deletions runtime/vm_builtin_test.go
Expand Up @@ -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")
Expand All @@ -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)
Expand All @@ -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())
Expand All @@ -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
Expand All @@ -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)
Expand Down

0 comments on commit a747c98

Please sign in to comment.