separate objects conversion functions
This commit is contained in:
parent
cb5cbad3ad
commit
552e9c01c5
3 changed files with 174 additions and 56 deletions
|
@ -1,22 +1,20 @@
|
||||||
package objects
|
package objects
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
func builtinString(args ...Object) (Object, error) {
|
func builtinString(args ...Object) (Object, error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, ErrWrongNumArguments
|
return nil, ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
switch arg := args[0].(type) {
|
if _, ok := args[0].(*String); ok {
|
||||||
case *String:
|
return args[0], nil
|
||||||
return arg, nil
|
|
||||||
case *Undefined:
|
|
||||||
return UndefinedValue, nil
|
|
||||||
default:
|
|
||||||
return &String{Value: arg.String()}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v, ok := ToString(args[0])
|
||||||
|
if ok {
|
||||||
|
return &String{Value: v}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return UndefinedValue, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func builtinInt(args ...Object) (Object, error) {
|
func builtinInt(args ...Object) (Object, error) {
|
||||||
|
@ -24,23 +22,13 @@ func builtinInt(args ...Object) (Object, error) {
|
||||||
return nil, ErrWrongNumArguments
|
return nil, ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
switch arg := args[0].(type) {
|
if _, ok := args[0].(*Int); ok {
|
||||||
case *Int:
|
return args[0], nil
|
||||||
return arg, nil
|
}
|
||||||
case *Float:
|
|
||||||
return &Int{Value: int64(arg.Value)}, nil
|
v, ok := ToInt64(args[0])
|
||||||
case *Char:
|
if ok {
|
||||||
return &Int{Value: int64(arg.Value)}, nil
|
return &Int{Value: v}, nil
|
||||||
case *Bool:
|
|
||||||
if arg.Value {
|
|
||||||
return &Int{Value: 1}, nil
|
|
||||||
}
|
|
||||||
return &Int{Value: 0}, nil
|
|
||||||
case *String:
|
|
||||||
n, err := strconv.ParseInt(arg.Value, 10, 64)
|
|
||||||
if err == nil {
|
|
||||||
return &Int{Value: n}, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return UndefinedValue, nil
|
return UndefinedValue, nil
|
||||||
|
@ -51,16 +39,13 @@ func builtinFloat(args ...Object) (Object, error) {
|
||||||
return nil, ErrWrongNumArguments
|
return nil, ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
switch arg := args[0].(type) {
|
if _, ok := args[0].(*Float); ok {
|
||||||
case *Float:
|
return args[0], nil
|
||||||
return arg, nil
|
}
|
||||||
case *Int:
|
|
||||||
return &Float{Value: float64(arg.Value)}, nil
|
v, ok := ToFloat64(args[0])
|
||||||
case *String:
|
if ok {
|
||||||
f, err := strconv.ParseFloat(arg.Value, 64)
|
return &Float{Value: v}, nil
|
||||||
if err == nil {
|
|
||||||
return &Float{Value: f}, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return UndefinedValue, nil
|
return UndefinedValue, nil
|
||||||
|
@ -71,12 +56,16 @@ func builtinBool(args ...Object) (Object, error) {
|
||||||
return nil, ErrWrongNumArguments
|
return nil, ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
switch arg := args[0].(type) {
|
if _, ok := args[0].(*Bool); ok {
|
||||||
case *Bool:
|
return args[0], nil
|
||||||
return arg, nil
|
|
||||||
default:
|
|
||||||
return &Bool{Value: !arg.IsFalsy()}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v, ok := ToBool(args[0])
|
||||||
|
if ok {
|
||||||
|
return &Bool{Value: v}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return UndefinedValue, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func builtinChar(args ...Object) (Object, error) {
|
func builtinChar(args ...Object) (Object, error) {
|
||||||
|
@ -84,19 +73,13 @@ func builtinChar(args ...Object) (Object, error) {
|
||||||
return nil, ErrWrongNumArguments
|
return nil, ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
switch arg := args[0].(type) {
|
if _, ok := args[0].(*Char); ok {
|
||||||
case *Char:
|
return args[0], nil
|
||||||
return arg, nil
|
}
|
||||||
case *Int:
|
|
||||||
return &Char{Value: rune(arg.Value)}, nil
|
v, ok := ToRune(args[0])
|
||||||
case *String:
|
if ok {
|
||||||
rs := []rune(arg.Value)
|
return &Char{Value: v}, nil
|
||||||
switch len(rs) {
|
|
||||||
case 0:
|
|
||||||
return &Char{}, nil
|
|
||||||
case 1:
|
|
||||||
return &Char{Value: rs[0]}, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return UndefinedValue, nil
|
return UndefinedValue, nil
|
||||||
|
|
132
objects/conversion.go
Normal file
132
objects/conversion.go
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
package objects
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ToString will try to convert object o to string value.
|
||||||
|
func ToString(o Object) (v string, ok bool) {
|
||||||
|
if _, isUndefined := o.(*Undefined); isUndefined {
|
||||||
|
//ok = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = true
|
||||||
|
|
||||||
|
if str, isStr := o.(*String); isStr {
|
||||||
|
v = str.Value
|
||||||
|
} else {
|
||||||
|
v = o.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToInt will try to convert object o to int value.
|
||||||
|
func ToInt(o Object) (v int, ok bool) {
|
||||||
|
switch o := o.(type) {
|
||||||
|
case *Int:
|
||||||
|
v = int(o.Value)
|
||||||
|
ok = true
|
||||||
|
case *Float:
|
||||||
|
v = int(o.Value)
|
||||||
|
ok = true
|
||||||
|
case *Char:
|
||||||
|
v = int(o.Value)
|
||||||
|
ok = true
|
||||||
|
case *Bool:
|
||||||
|
if o.Value {
|
||||||
|
v = 1
|
||||||
|
}
|
||||||
|
ok = true
|
||||||
|
case *String:
|
||||||
|
c, err := strconv.ParseInt(o.Value, 10, 64)
|
||||||
|
if err == nil {
|
||||||
|
v = int(c)
|
||||||
|
ok = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//ok = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToInt64 will try to convert object o to int64 value.
|
||||||
|
func ToInt64(o Object) (v int64, ok bool) {
|
||||||
|
switch o := o.(type) {
|
||||||
|
case *Int:
|
||||||
|
v = o.Value
|
||||||
|
ok = true
|
||||||
|
case *Float:
|
||||||
|
v = int64(o.Value)
|
||||||
|
ok = true
|
||||||
|
case *Char:
|
||||||
|
v = int64(o.Value)
|
||||||
|
ok = true
|
||||||
|
case *Bool:
|
||||||
|
if o.Value {
|
||||||
|
v = 1
|
||||||
|
}
|
||||||
|
ok = true
|
||||||
|
case *String:
|
||||||
|
c, err := strconv.ParseInt(o.Value, 10, 64)
|
||||||
|
if err == nil {
|
||||||
|
v = c
|
||||||
|
ok = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//ok = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToFloat64 will try to convert object o to float64 value.
|
||||||
|
func ToFloat64(o Object) (v float64, ok bool) {
|
||||||
|
switch o := o.(type) {
|
||||||
|
case *Int:
|
||||||
|
v = float64(o.Value)
|
||||||
|
ok = true
|
||||||
|
case *Float:
|
||||||
|
v = o.Value
|
||||||
|
ok = true
|
||||||
|
case *String:
|
||||||
|
c, err := strconv.ParseFloat(o.Value, 64)
|
||||||
|
if err == nil {
|
||||||
|
v = c
|
||||||
|
ok = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//ok = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToBool will try to convert object o to bool value.
|
||||||
|
func ToBool(o Object) (v bool, ok bool) {
|
||||||
|
ok = true
|
||||||
|
v = !o.IsFalsy()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToRune will try to convert object o to rune value.
|
||||||
|
func ToRune(o Object) (v rune, ok bool) {
|
||||||
|
switch o := o.(type) {
|
||||||
|
case *Int:
|
||||||
|
v = rune(o.Value)
|
||||||
|
ok = true
|
||||||
|
case *Char:
|
||||||
|
v = rune(o.Value)
|
||||||
|
ok = true
|
||||||
|
case *String:
|
||||||
|
rs := []rune(o.Value)
|
||||||
|
switch len(rs) {
|
||||||
|
case 1:
|
||||||
|
v = rs[0]
|
||||||
|
ok = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//ok = false
|
||||||
|
return
|
||||||
|
}
|
|
@ -7,3 +7,6 @@ var ErrInvalidOperator = errors.New("invalid operator")
|
||||||
|
|
||||||
// ErrWrongNumArguments represents a wrong number of arguments error.
|
// ErrWrongNumArguments represents a wrong number of arguments error.
|
||||||
var ErrWrongNumArguments = errors.New("wrong number of arguments")
|
var ErrWrongNumArguments = errors.New("wrong number of arguments")
|
||||||
|
|
||||||
|
// ErrInvalidTypeConversion represents an invalid type conversion error.
|
||||||
|
var ErrInvalidTypeConversion = errors.New("invalid type conversion")
|
||||||
|
|
Loading…
Reference in a new issue