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
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func builtinString(args ...Object) (Object, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, ErrWrongNumArguments
|
||||
}
|
||||
|
||||
switch arg := args[0].(type) {
|
||||
case *String:
|
||||
return arg, nil
|
||||
case *Undefined:
|
||||
return UndefinedValue, nil
|
||||
default:
|
||||
return &String{Value: arg.String()}, nil
|
||||
if _, ok := args[0].(*String); ok {
|
||||
return args[0], nil
|
||||
}
|
||||
|
||||
v, ok := ToString(args[0])
|
||||
if ok {
|
||||
return &String{Value: v}, nil
|
||||
}
|
||||
|
||||
return UndefinedValue, nil
|
||||
}
|
||||
|
||||
func builtinInt(args ...Object) (Object, error) {
|
||||
|
@ -24,23 +22,13 @@ func builtinInt(args ...Object) (Object, error) {
|
|||
return nil, ErrWrongNumArguments
|
||||
}
|
||||
|
||||
switch arg := args[0].(type) {
|
||||
case *Int:
|
||||
return arg, nil
|
||||
case *Float:
|
||||
return &Int{Value: int64(arg.Value)}, nil
|
||||
case *Char:
|
||||
return &Int{Value: int64(arg.Value)}, 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
|
||||
}
|
||||
if _, ok := args[0].(*Int); ok {
|
||||
return args[0], nil
|
||||
}
|
||||
|
||||
v, ok := ToInt64(args[0])
|
||||
if ok {
|
||||
return &Int{Value: v}, nil
|
||||
}
|
||||
|
||||
return UndefinedValue, nil
|
||||
|
@ -51,16 +39,13 @@ func builtinFloat(args ...Object) (Object, error) {
|
|||
return nil, ErrWrongNumArguments
|
||||
}
|
||||
|
||||
switch arg := args[0].(type) {
|
||||
case *Float:
|
||||
return arg, nil
|
||||
case *Int:
|
||||
return &Float{Value: float64(arg.Value)}, nil
|
||||
case *String:
|
||||
f, err := strconv.ParseFloat(arg.Value, 64)
|
||||
if err == nil {
|
||||
return &Float{Value: f}, nil
|
||||
}
|
||||
if _, ok := args[0].(*Float); ok {
|
||||
return args[0], nil
|
||||
}
|
||||
|
||||
v, ok := ToFloat64(args[0])
|
||||
if ok {
|
||||
return &Float{Value: v}, nil
|
||||
}
|
||||
|
||||
return UndefinedValue, nil
|
||||
|
@ -71,12 +56,16 @@ func builtinBool(args ...Object) (Object, error) {
|
|||
return nil, ErrWrongNumArguments
|
||||
}
|
||||
|
||||
switch arg := args[0].(type) {
|
||||
case *Bool:
|
||||
return arg, nil
|
||||
default:
|
||||
return &Bool{Value: !arg.IsFalsy()}, nil
|
||||
if _, ok := args[0].(*Bool); ok {
|
||||
return args[0], nil
|
||||
}
|
||||
|
||||
v, ok := ToBool(args[0])
|
||||
if ok {
|
||||
return &Bool{Value: v}, nil
|
||||
}
|
||||
|
||||
return UndefinedValue, nil
|
||||
}
|
||||
|
||||
func builtinChar(args ...Object) (Object, error) {
|
||||
|
@ -84,19 +73,13 @@ func builtinChar(args ...Object) (Object, error) {
|
|||
return nil, ErrWrongNumArguments
|
||||
}
|
||||
|
||||
switch arg := args[0].(type) {
|
||||
case *Char:
|
||||
return arg, nil
|
||||
case *Int:
|
||||
return &Char{Value: rune(arg.Value)}, nil
|
||||
case *String:
|
||||
rs := []rune(arg.Value)
|
||||
switch len(rs) {
|
||||
case 0:
|
||||
return &Char{}, nil
|
||||
case 1:
|
||||
return &Char{Value: rs[0]}, nil
|
||||
}
|
||||
if _, ok := args[0].(*Char); ok {
|
||||
return args[0], nil
|
||||
}
|
||||
|
||||
v, ok := ToRune(args[0])
|
||||
if ok {
|
||||
return &Char{Value: v}, 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.
|
||||
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