add some more os module functions, add more built-int functions

This commit is contained in:
Daniel Kang 2019-01-17 21:23:20 -08:00
parent a14f6ec1c0
commit 44c55ea296
8 changed files with 568 additions and 91 deletions

View file

@ -175,6 +175,10 @@ func Equal(t *testing.T, expected, actual interface{}, msg ...interface{}) bool
return true
case *objects.Error:
return Equal(t, expected.Value, actual.(*objects.Error).Value)
case error:
if expected != actual.(error) {
return failExpectedActual(t, expected, actual, msg...)
}
default:
panic(fmt.Errorf("type not implemented: %T", expected))
}

View file

@ -20,6 +20,53 @@ func FuncAR(fn func()) *objects.UserFunction {
}
}
// FuncARI transform a function of 'func() int' signature
// into a user function object.
func FuncARI(fn func() int) *objects.UserFunction {
return &objects.UserFunction{
Value: func(args ...objects.Object) (ret objects.Object, err error) {
if len(args) != 0 {
return nil, objects.ErrWrongNumArguments
}
return &objects.Int{Value: int64(fn())}, nil
},
}
}
// FuncARS transform a function of 'func() string' signature
// into a user function object.
func FuncARS(fn func() string) *objects.UserFunction {
return &objects.UserFunction{
Value: func(args ...objects.Object) (ret objects.Object, err error) {
if len(args) != 0 {
return nil, objects.ErrWrongNumArguments
}
return &objects.String{Value: fn()}, nil
},
}
}
// FuncARSE transform a function of 'func() (string, error)' signature
// into a user function object.
func FuncARSE(fn func() (string, error)) *objects.UserFunction {
return &objects.UserFunction{
Value: func(args ...objects.Object) (ret objects.Object, err error) {
if len(args) != 0 {
return nil, objects.ErrWrongNumArguments
}
res, err := fn()
if err != nil {
return wrapError(err), nil
}
return &objects.String{Value: res}, nil
},
}
}
// FuncARF transform a function of 'func() float64' signature
// into a user function object.
func FuncARF(fn func() float64) *objects.UserFunction {
@ -53,6 +100,30 @@ func FuncARSs(fn func() []string) *objects.UserFunction {
}
}
// FuncARIsE transform a function of 'func() ([]int, error)' signature
// into a user function object.
func FuncARIsE(fn func() ([]int, error)) *objects.UserFunction {
return &objects.UserFunction{
Value: func(args ...objects.Object) (ret objects.Object, err error) {
if len(args) != 0 {
return nil, objects.ErrWrongNumArguments
}
res, err := fn()
if err != nil {
return wrapError(err), nil
}
arr := &objects.Array{}
for _, v := range res {
arr.Value = append(arr.Value, &objects.Int{Value: int64(v)})
}
return arr, nil
},
}
}
// FuncAFRF transform a function of 'func(float64) float64' signature
// into a user function object.
func FuncAFRF(fn func(float64) float64) *objects.UserFunction {
@ -72,6 +143,27 @@ func FuncAFRF(fn func(float64) float64) *objects.UserFunction {
}
}
// FuncAIR transform a function of 'func(int)' signature
// into a user function object.
func FuncAIR(fn func(int)) *objects.UserFunction {
return &objects.UserFunction{
Value: func(args ...objects.Object) (ret objects.Object, err error) {
if len(args) != 1 {
return nil, objects.ErrWrongNumArguments
}
i1, ok := objects.ToInt(args[0])
if !ok {
return nil, objects.ErrInvalidTypeConversion
}
fn(i1)
return objects.UndefinedValue, nil
},
}
}
// FuncAIRF transform a function of 'func(int) float64' signature
// into a user function object.
func FuncAIRF(fn func(int) float64) *objects.UserFunction {
@ -225,6 +317,49 @@ func FuncAFRB(fn func(float64) bool) *objects.UserFunction {
}
}
// FuncASRS transform a function of 'func(string) string' signature into a user function object.
// User function will return 'true' if underlying native function returns nil.
func FuncASRS(fn func(string) string) *objects.UserFunction {
return &objects.UserFunction{
Value: func(args ...objects.Object) (objects.Object, error) {
if len(args) != 1 {
return nil, objects.ErrWrongNumArguments
}
s1, ok := objects.ToString(args[0])
if !ok {
return nil, objects.ErrInvalidTypeConversion
}
return &objects.String{Value: fn(s1)}, nil
},
}
}
// FuncASRSE transform a function of 'func(string) (string, error)' signature into a user function object.
// User function will return 'true' if underlying native function returns nil.
func FuncASRSE(fn func(string) (string, error)) *objects.UserFunction {
return &objects.UserFunction{
Value: func(args ...objects.Object) (objects.Object, error) {
if len(args) != 1 {
return nil, objects.ErrWrongNumArguments
}
s1, ok := objects.ToString(args[0])
if !ok {
return nil, objects.ErrInvalidTypeConversion
}
res, err := fn(s1)
if err != nil {
return wrapError(err), nil
}
return &objects.String{Value: res}, nil
},
}
}
// FuncASRE transform a function of 'func(string) error' signature into a user function object.
// User function will return 'true' if underlying native function returns nil.
func FuncASRE(fn func(string) error) *objects.UserFunction {
@ -243,3 +378,80 @@ func FuncASRE(fn func(string) error) *objects.UserFunction {
},
}
}
// FuncASSRE transform a function of 'func(string, string) error' signature into a user function object.
// User function will return 'true' if underlying native function returns nil.
func FuncASSRE(fn func(string, string) error) *objects.UserFunction {
return &objects.UserFunction{
Value: func(args ...objects.Object) (objects.Object, error) {
if len(args) != 2 {
return nil, objects.ErrWrongNumArguments
}
s1, ok := objects.ToString(args[0])
if !ok {
return nil, objects.ErrInvalidTypeConversion
}
s2, ok := objects.ToString(args[1])
if !ok {
return nil, objects.ErrInvalidTypeConversion
}
return wrapError(fn(s1, s2)), nil
},
}
}
// FuncASI64RE transform a function of 'func(string, int64) error' signature
// into a user function object.
func FuncASI64RE(fn func(string, int64) error) *objects.UserFunction {
return &objects.UserFunction{
Value: func(args ...objects.Object) (ret objects.Object, err error) {
if len(args) != 2 {
return nil, objects.ErrWrongNumArguments
}
s1, ok := objects.ToString(args[0])
if !ok {
return nil, objects.ErrInvalidTypeConversion
}
i2, ok := objects.ToInt64(args[1])
if !ok {
return nil, objects.ErrInvalidTypeConversion
}
return wrapError(fn(s1, i2)), nil
},
}
}
// FuncASIIRE transform a function of 'func(string, int, int) error' signature
// into a user function object.
func FuncASIIRE(fn func(string, int, int) error) *objects.UserFunction {
return &objects.UserFunction{
Value: func(args ...objects.Object) (ret objects.Object, err error) {
if len(args) != 3 {
return nil, objects.ErrWrongNumArguments
}
s1, ok := objects.ToString(args[0])
if !ok {
return nil, objects.ErrInvalidTypeConversion
}
i2, ok := objects.ToInt(args[1])
if !ok {
return nil, objects.ErrInvalidTypeConversion
}
i3, ok := objects.ToInt(args[2])
if !ok {
return nil, objects.ErrInvalidTypeConversion
}
return wrapError(fn(s1, i2, i3)), nil
},
}
}

View file

@ -1,6 +1,7 @@
package stdmods_test
import (
"errors"
"testing"
"github.com/d5/tengo/assert"
@ -8,6 +9,142 @@ import (
"github.com/d5/tengo/objects"
)
func TestFuncAIR(t *testing.T) {
uf := stdmods.FuncAIR(func(int) {})
ret, err := uf.Call(&objects.Int{Value: 10})
assert.NoError(t, err)
assert.Equal(t, &objects.Undefined{}, ret)
ret, err = uf.Call()
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncAR(t *testing.T) {
uf := stdmods.FuncAR(func() {})
ret, err := uf.Call()
assert.NoError(t, err)
assert.Equal(t, &objects.Undefined{}, ret)
ret, err = uf.Call(objects.TrueValue)
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncARI(t *testing.T) {
uf := stdmods.FuncARI(func() int { return 10 })
ret, err := uf.Call()
assert.NoError(t, err)
assert.Equal(t, &objects.Int{Value: 10}, ret)
ret, err = uf.Call(objects.TrueValue)
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncARIsE(t *testing.T) {
uf := stdmods.FuncARIsE(func() ([]int, error) { return []int{1, 2, 3}, nil })
ret, err := uf.Call()
assert.NoError(t, err)
assert.Equal(t, array(&objects.Int{Value: 1}, &objects.Int{Value: 2}, &objects.Int{Value: 3}), ret)
uf = stdmods.FuncARIsE(func() ([]int, error) { return nil, errors.New("some error") })
ret, err = uf.Call()
assert.NoError(t, err)
assert.Equal(t, &objects.Error{Value: &objects.String{Value: "some error"}}, ret)
ret, err = uf.Call(objects.TrueValue)
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncARS(t *testing.T) {
uf := stdmods.FuncARS(func() string { return "foo" })
ret, err := uf.Call()
assert.NoError(t, err)
assert.Equal(t, &objects.String{Value: "foo"}, ret)
ret, err = uf.Call(objects.TrueValue)
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncARSE(t *testing.T) {
uf := stdmods.FuncARSE(func() (string, error) { return "foo", nil })
ret, err := uf.Call()
assert.NoError(t, err)
assert.Equal(t, &objects.String{Value: "foo"}, ret)
uf = stdmods.FuncARSE(func() (string, error) { return "", errors.New("some error") })
ret, err = uf.Call()
assert.NoError(t, err)
assert.Equal(t, &objects.Error{Value: &objects.String{Value: "some error"}}, ret)
ret, err = uf.Call(objects.TrueValue)
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncARSs(t *testing.T) {
uf := stdmods.FuncARSs(func() []string { return []string{"foo", "bar"} })
ret, err := uf.Call()
assert.NoError(t, err)
assert.Equal(t, array(&objects.String{Value: "foo"}, &objects.String{Value: "bar"}), ret)
ret, err = uf.Call(objects.TrueValue)
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncASRE(t *testing.T) {
uf := stdmods.FuncASRE(func(a string) error { return nil })
ret, err := uf.Call(&objects.String{Value: "foo"})
assert.NoError(t, err)
assert.Equal(t, objects.TrueValue, ret)
uf = stdmods.FuncASRE(func(a string) error { return errors.New("some error") })
ret, err = uf.Call(&objects.String{Value: "foo"})
assert.NoError(t, err)
assert.Equal(t, &objects.Error{Value: &objects.String{Value: "some error"}}, ret)
ret, err = uf.Call()
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncASRS(t *testing.T) {
uf := stdmods.FuncASRS(func(a string) string { return a })
ret, err := uf.Call(&objects.String{Value: "foo"})
assert.NoError(t, err)
assert.Equal(t, &objects.String{Value: "foo"}, ret)
ret, err = uf.Call()
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncASI64RE(t *testing.T) {
uf := stdmods.FuncASI64RE(func(a string, b int64) error { return nil })
ret, err := uf.Call(&objects.String{Value: "foo"}, &objects.Int{Value: 5})
assert.NoError(t, err)
assert.Equal(t, objects.TrueValue, ret)
uf = stdmods.FuncASI64RE(func(a string, b int64) error { return errors.New("some error") })
ret, err = uf.Call(&objects.String{Value: "foo"}, &objects.Int{Value: 5})
assert.NoError(t, err)
assert.Equal(t, &objects.Error{Value: &objects.String{Value: "some error"}}, ret)
ret, err = uf.Call()
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncASIIRE(t *testing.T) {
uf := stdmods.FuncASIIRE(func(a string, b, c int) error { return nil })
ret, err := uf.Call(&objects.String{Value: "foo"}, &objects.Int{Value: 5}, &objects.Int{Value: 7})
assert.NoError(t, err)
assert.Equal(t, objects.TrueValue, ret)
uf = stdmods.FuncASIIRE(func(a string, b, c int) error { return errors.New("some error") })
ret, err = uf.Call(&objects.String{Value: "foo"}, &objects.Int{Value: 5}, &objects.Int{Value: 7})
assert.NoError(t, err)
assert.Equal(t, &objects.Error{Value: &objects.String{Value: "some error"}}, ret)
ret, err = uf.Call()
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncASRSE(t *testing.T) {
uf := stdmods.FuncASRSE(func(a string) (string, error) { return a, nil })
ret, err := uf.Call(&objects.String{Value: "foo"})
assert.NoError(t, err)
assert.Equal(t, &objects.String{Value: "foo"}, ret)
uf = stdmods.FuncASRSE(func(a string) (string, error) { return a, errors.New("some error") })
ret, err = uf.Call(&objects.String{Value: "foo"})
assert.NoError(t, err)
assert.Equal(t, &objects.Error{Value: &objects.String{Value: "some error"}}, ret)
ret, err = uf.Call()
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncASSRE(t *testing.T) {
}
func TestFuncARF(t *testing.T) {
uf := stdmods.FuncARF(func() float64 {
return 10.0
@ -16,7 +153,7 @@ func TestFuncARF(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, &objects.Float{Value: 10.0}, ret)
ret, err = uf.Call(objects.TrueValue)
assert.Error(t, err)
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncAFRF(t *testing.T) {
@ -27,9 +164,9 @@ func TestFuncAFRF(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, &objects.Float{Value: 10.0}, ret)
ret, err = uf.Call()
assert.Error(t, err)
assert.Equal(t, objects.ErrWrongNumArguments, err)
ret, err = uf.Call(objects.TrueValue, objects.TrueValue)
assert.Error(t, err)
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncAIRF(t *testing.T) {
@ -40,9 +177,9 @@ func TestFuncAIRF(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, &objects.Float{Value: 10.0}, ret)
ret, err = uf.Call()
assert.Error(t, err)
assert.Equal(t, objects.ErrWrongNumArguments, err)
ret, err = uf.Call(objects.TrueValue, objects.TrueValue)
assert.Error(t, err)
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncAFRI(t *testing.T) {
@ -53,9 +190,9 @@ func TestFuncAFRI(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, &objects.Int{Value: 10}, ret)
ret, err = uf.Call()
assert.Error(t, err)
assert.Equal(t, objects.ErrWrongNumArguments, err)
ret, err = uf.Call(objects.TrueValue, objects.TrueValue)
assert.Error(t, err)
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncAFRB(t *testing.T) {
@ -66,9 +203,9 @@ func TestFuncAFRB(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, &objects.Bool{Value: true}, ret)
ret, err = uf.Call()
assert.Error(t, err)
assert.Equal(t, objects.ErrWrongNumArguments, err)
ret, err = uf.Call(objects.TrueValue, objects.TrueValue)
assert.Error(t, err)
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncAFFRF(t *testing.T) {
@ -79,9 +216,9 @@ func TestFuncAFFRF(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, &objects.Float{Value: 30.0}, ret)
ret, err = uf.Call()
assert.Error(t, err)
assert.Equal(t, objects.ErrWrongNumArguments, err)
ret, err = uf.Call(objects.TrueValue)
assert.Error(t, err)
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncAIFRF(t *testing.T) {
@ -92,9 +229,9 @@ func TestFuncAIFRF(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, &objects.Float{Value: 30.0}, ret)
ret, err = uf.Call()
assert.Error(t, err)
assert.Equal(t, objects.ErrWrongNumArguments, err)
ret, err = uf.Call(objects.TrueValue)
assert.Error(t, err)
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncAFIRF(t *testing.T) {
@ -105,9 +242,9 @@ func TestFuncAFIRF(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, &objects.Float{Value: 30.0}, ret)
ret, err = uf.Call()
assert.Error(t, err)
assert.Equal(t, objects.ErrWrongNumArguments, err)
ret, err = uf.Call(objects.TrueValue)
assert.Error(t, err)
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func TestFuncAFIRB(t *testing.T) {
@ -118,7 +255,11 @@ func TestFuncAFIRB(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, &objects.Bool{Value: true}, ret)
ret, err = uf.Call()
assert.Error(t, err)
assert.Equal(t, objects.ErrWrongNumArguments, err)
ret, err = uf.Call(objects.TrueValue)
assert.Error(t, err)
assert.Equal(t, objects.ErrWrongNumArguments, err)
}
func array(elements ...objects.Object) *objects.Array {
return &objects.Array{Value: elements}
}

View file

@ -36,19 +36,56 @@ var osModule = map[string]objects.Object{
"path_list_separator": &objects.Char{Value: os.PathListSeparator},
"dev_null": &objects.String{Value: os.DevNull},
"args": &objects.UserFunction{Value: osArgs},
"chdir": FuncASRE(os.Chdir),
"chmod": &objects.UserFunction{Value: osChmod},
"chown": &objects.UserFunction{Value: osChown},
"clearenv": FuncAR(os.Clearenv),
"environ": FuncARSs(os.Environ),
"args": &objects.UserFunction{Value: osArgs},
"chdir": FuncASRE(os.Chdir),
"chmod": osFuncASFmRE(os.Chmod),
"chown": FuncASIIRE(os.Chown),
"clearenv": FuncAR(os.Clearenv),
"environ": FuncARSs(os.Environ),
"executable": &objects.UserFunction{Value: osExecutable},
"exit": FuncAIR(os.Exit),
"expand_env": FuncASRS(os.ExpandEnv),
"getegid": FuncARI(os.Getegid),
"getenv": FuncASRS(os.Getenv),
"geteuid": FuncARI(os.Geteuid),
"getgid": FuncARI(os.Getgid),
"getgroups": FuncARIsE(os.Getgroups),
"getpagesize": FuncARI(os.Getpagesize),
"getpid": FuncARI(os.Getpid),
"getppid": FuncARI(os.Getppid),
"getuid": FuncARI(os.Getuid),
"getwd": FuncARSE(os.Getwd),
"hostname": FuncARSE(os.Hostname),
"lchown": FuncASIIRE(os.Lchown),
"link": FuncASSRE(os.Link),
"lookup_env": &objects.UserFunction{Value: osLookupEnv},
"mkdir": osFuncASFmRE(os.Mkdir),
"mkdir_all": osFuncASFmRE(os.MkdirAll),
"readlink": FuncASRSE(os.Readlink),
"remove": FuncASRE(os.Remove),
"remove_all": FuncASRE(os.RemoveAll),
"rename": FuncASSRE(os.Rename),
"setenv": FuncASSRE(os.Setenv),
"symlink": FuncASSRE(os.Symlink),
"temp_dir": FuncARS(os.TempDir),
"truncate": FuncASI64RE(os.Truncate),
"unsetenv": FuncASRE(os.Unsetenv),
"user_cache_dir": FuncARSE(os.UserCacheDir),
// TODO: system errors
//"err_invalid": &objects.Error{Value: os.ErrInvalid.Error()},
// TODO: STDIN, STDOUT, STDERR
// "stdin": nil,
// "stdout": nil,
// "stderr": nil,
// TODO: not implemented yet
//"stdin": nil,
//"stdout": nil,
//"stderr": nil,
//"chtimes": nil,
//"expand": nil,
//"is_exists": nil,
//"is_not_exist": nil,
//"is_path_separator": nil,
//"is_permission": nil,
//"is_timeout": nil,
//"new_syscall_error": nil,
//"pipe": nil,
//"same_file": nil,
}
func osArgs(args ...objects.Object) (objects.Object, error) {
@ -64,8 +101,42 @@ func osArgs(args ...objects.Object) (objects.Object, error) {
return arr, nil
}
func osChmod(args ...objects.Object) (objects.Object, error) {
if len(args) != 2 {
func osFuncASFmRE(fn func(string, os.FileMode) error) *objects.UserFunction {
return &objects.UserFunction{
Value: func(args ...objects.Object) (objects.Object, error) {
if len(args) != 2 {
return nil, objects.ErrWrongNumArguments
}
s1, ok := objects.ToString(args[0])
if !ok {
return nil, objects.ErrInvalidTypeConversion
}
i2, ok := objects.ToInt(args[1])
if !ok {
return nil, objects.ErrInvalidTypeConversion
}
return wrapError(fn(s1, os.FileMode(i2))), nil
},
}
}
func osExecutable(args ...objects.Object) (objects.Object, error) {
if len(args) != 0 {
return nil, objects.ErrWrongNumArguments
}
res, err := os.Executable()
if err != nil {
return wrapError(err), nil
}
return &objects.String{Value: res}, nil
}
func osLookupEnv(args ...objects.Object) (objects.Object, error) {
if len(args) != 1 {
return nil, objects.ErrWrongNumArguments
}
@ -73,31 +144,11 @@ func osChmod(args ...objects.Object) (objects.Object, error) {
if !ok {
return nil, objects.ErrInvalidTypeConversion
}
i2, ok := objects.ToInt(args[1])
res, ok := os.LookupEnv(s1)
if !ok {
return nil, objects.ErrInvalidTypeConversion
return objects.FalseValue, nil
}
return wrapError(os.Chmod(s1, os.FileMode(i2))), nil
}
func osChown(args ...objects.Object) (objects.Object, error) {
if len(args) != 3 {
return nil, objects.ErrWrongNumArguments
}
s1, ok := objects.ToString(args[0])
if !ok {
return nil, objects.ErrInvalidTypeConversion
}
i2, ok := objects.ToInt(args[1])
if !ok {
return nil, objects.ErrInvalidTypeConversion
}
i3, ok := objects.ToInt(args[2])
if !ok {
return nil, objects.ErrInvalidTypeConversion
}
return wrapError(os.Chown(s1, i2, i3)), nil
return &objects.String{Value: res}, nil
}

View file

@ -1,18 +0,0 @@
package objects
import (
"fmt"
)
func builtinIsError(args ...Object) (Object, error) {
if len(args) != 1 {
return nil, fmt.Errorf("wrong number of arguments (got=%d, want=1)", len(args))
}
switch args[0].(type) {
case *Error:
return TrueValue, nil
}
return FalseValue, nil
}

View file

@ -1,18 +0,0 @@
package objects
import (
"fmt"
)
func builtinIsUndefined(args ...Object) (Object, error) {
if len(args) != 1 {
return nil, fmt.Errorf("wrong number of arguments (got=%d, want=1)", len(args))
}
switch args[0].(type) {
case *Undefined:
return TrueValue, nil
}
return FalseValue, nil
}

View file

@ -0,0 +1,85 @@
package objects
func builtinIsString(args ...Object) (Object, error) {
if len(args) != 1 {
return nil, ErrWrongNumArguments
}
if _, ok := args[0].(*String); ok {
return TrueValue, nil
}
return FalseValue, nil
}
func builtinIsInt(args ...Object) (Object, error) {
if len(args) != 1 {
return nil, ErrWrongNumArguments
}
if _, ok := args[0].(*Int); ok {
return TrueValue, nil
}
return FalseValue, nil
}
func builtinIsFloat(args ...Object) (Object, error) {
if len(args) != 1 {
return nil, ErrWrongNumArguments
}
if _, ok := args[0].(*Float); ok {
return TrueValue, nil
}
return FalseValue, nil
}
func builtinIsBool(args ...Object) (Object, error) {
if len(args) != 1 {
return nil, ErrWrongNumArguments
}
if _, ok := args[0].(*Bool); ok {
return TrueValue, nil
}
return FalseValue, nil
}
func builtinIsChar(args ...Object) (Object, error) {
if len(args) != 1 {
return nil, ErrWrongNumArguments
}
if _, ok := args[0].(*Char); ok {
return TrueValue, nil
}
return FalseValue, nil
}
func builtinIsError(args ...Object) (Object, error) {
if len(args) != 1 {
return nil, ErrWrongNumArguments
}
if _, ok := args[0].(*Error); ok {
return TrueValue, nil
}
return FalseValue, nil
}
func builtinIsUndefined(args ...Object) (Object, error) {
if len(args) != 1 {
return nil, ErrWrongNumArguments
}
if _, ok := args[0].(*Undefined); ok {
return TrueValue, nil
}
return FalseValue, nil
}

View file

@ -41,6 +41,26 @@ var Builtins = []struct {
Name: "char",
Func: builtinChar,
},
{
Name: "is_int",
Func: builtinIsInt,
},
{
Name: "is_float",
Func: builtinIsFloat,
},
{
Name: "is_string",
Func: builtinIsString,
},
{
Name: "is_bool",
Func: builtinIsBool,
},
{
Name: "is_char",
Func: builtinIsChar,
},
{
Name: "is_error",
Func: builtinIsError,