incomplete implementation of 'os' module
This commit is contained in:
parent
552e9c01c5
commit
a14f6ec1c0
4 changed files with 228 additions and 111 deletions
11
compiler/stdmods/errors.go
Normal file
11
compiler/stdmods/errors.go
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package stdmods
|
||||||
|
|
||||||
|
import "github.com/d5/tengo/objects"
|
||||||
|
|
||||||
|
func wrapError(err error) objects.Object {
|
||||||
|
if err == nil {
|
||||||
|
return objects.TrueValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return &objects.Error{Value: &objects.String{Value: err.Error()}}
|
||||||
|
}
|
|
@ -1,28 +1,21 @@
|
||||||
package stdmods
|
package stdmods
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/d5/tengo/objects"
|
"github.com/d5/tengo/objects"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FuncAFRF transform a function of 'func(float64) float64' signature
|
// FuncAR transform a function of 'func()' signature
|
||||||
// into a user function object.
|
// into a user function object.
|
||||||
func FuncAFRF(fn func(float64) float64) *objects.UserFunction {
|
func FuncAR(fn func()) *objects.UserFunction {
|
||||||
return &objects.UserFunction{
|
return &objects.UserFunction{
|
||||||
Value: func(args ...objects.Object) (ret objects.Object, err error) {
|
Value: func(args ...objects.Object) (ret objects.Object, err error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 0 {
|
||||||
return nil, objects.ErrWrongNumArguments
|
return nil, objects.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
switch arg := args[0].(type) {
|
fn()
|
||||||
case *objects.Int:
|
|
||||||
return &objects.Float{Value: fn(float64(arg.Value))}, nil
|
return objects.UndefinedValue, nil
|
||||||
case *objects.Float:
|
|
||||||
return &objects.Float{Value: fn(arg.Value)}, nil
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid argument type: %s", arg.TypeName())
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,6 +34,44 @@ func FuncARF(fn func() float64) *objects.UserFunction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FuncARSs transform a function of 'func() []string' signature
|
||||||
|
// into a user function object.
|
||||||
|
func FuncARSs(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
|
||||||
|
}
|
||||||
|
|
||||||
|
arr := &objects.Array{}
|
||||||
|
for _, osArg := range fn() {
|
||||||
|
arr.Value = append(arr.Value, &objects.String{Value: osArg})
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
return &objects.UserFunction{
|
||||||
|
Value: func(args ...objects.Object) (ret objects.Object, err error) {
|
||||||
|
if len(args) != 1 {
|
||||||
|
return nil, objects.ErrWrongNumArguments
|
||||||
|
}
|
||||||
|
|
||||||
|
f1, ok := objects.ToFloat64(args[0])
|
||||||
|
if !ok {
|
||||||
|
return nil, objects.ErrInvalidTypeConversion
|
||||||
|
}
|
||||||
|
|
||||||
|
return &objects.Float{Value: fn(f1)}, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FuncAIRF transform a function of 'func(int) float64' signature
|
// FuncAIRF transform a function of 'func(int) float64' signature
|
||||||
// into a user function object.
|
// into a user function object.
|
||||||
func FuncAIRF(fn func(int) float64) *objects.UserFunction {
|
func FuncAIRF(fn func(int) float64) *objects.UserFunction {
|
||||||
|
@ -50,14 +81,12 @@ func FuncAIRF(fn func(int) float64) *objects.UserFunction {
|
||||||
return nil, objects.ErrWrongNumArguments
|
return nil, objects.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
switch arg := args[0].(type) {
|
i1, ok := objects.ToInt(args[0])
|
||||||
case *objects.Int:
|
if !ok {
|
||||||
return &objects.Float{Value: fn(int(arg.Value))}, nil
|
return nil, objects.ErrInvalidTypeConversion
|
||||||
case *objects.Float:
|
|
||||||
return &objects.Float{Value: fn(int(arg.Value))}, nil
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid argument type: %s", arg.TypeName())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return &objects.Float{Value: fn(i1)}, nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,14 +100,12 @@ func FuncAFRI(fn func(float64) int) *objects.UserFunction {
|
||||||
return nil, objects.ErrWrongNumArguments
|
return nil, objects.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
switch arg := args[0].(type) {
|
f1, ok := objects.ToFloat64(args[0])
|
||||||
case *objects.Int:
|
if !ok {
|
||||||
return &objects.Int{Value: int64(fn(float64(arg.Value)))}, nil
|
return nil, objects.ErrInvalidTypeConversion
|
||||||
case *objects.Float:
|
|
||||||
return &objects.Int{Value: int64(fn(arg.Value))}, nil
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid argument type: %s", arg.TypeName())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return &objects.Int{Value: int64(fn(f1))}, nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,26 +119,17 @@ func FuncAFFRF(fn func(float64, float64) float64) *objects.UserFunction {
|
||||||
return nil, objects.ErrWrongNumArguments
|
return nil, objects.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
var arg0, arg1 float64
|
f1, ok := objects.ToFloat64(args[0])
|
||||||
|
if !ok {
|
||||||
switch arg := args[0].(type) {
|
return nil, objects.ErrInvalidTypeConversion
|
||||||
case *objects.Int:
|
|
||||||
arg0 = float64(arg.Value)
|
|
||||||
case *objects.Float:
|
|
||||||
arg0 = arg.Value
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid argument type: %s", arg.TypeName())
|
|
||||||
}
|
|
||||||
switch arg := args[1].(type) {
|
|
||||||
case *objects.Int:
|
|
||||||
arg1 = float64(arg.Value)
|
|
||||||
case *objects.Float:
|
|
||||||
arg1 = arg.Value
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid argument type: %s", arg.TypeName())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &objects.Float{Value: fn(arg0, arg1)}, nil
|
f2, ok := objects.ToFloat64(args[1])
|
||||||
|
if !ok {
|
||||||
|
return nil, objects.ErrInvalidTypeConversion
|
||||||
|
}
|
||||||
|
|
||||||
|
return &objects.Float{Value: fn(f1, f2)}, nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,27 +143,17 @@ func FuncAIFRF(fn func(int, float64) float64) *objects.UserFunction {
|
||||||
return nil, objects.ErrWrongNumArguments
|
return nil, objects.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
var arg0 int
|
i1, ok := objects.ToInt(args[0])
|
||||||
var arg1 float64
|
if !ok {
|
||||||
|
return nil, objects.ErrInvalidTypeConversion
|
||||||
switch arg := args[0].(type) {
|
|
||||||
case *objects.Int:
|
|
||||||
arg0 = int(arg.Value)
|
|
||||||
case *objects.Float:
|
|
||||||
arg0 = int(arg.Value)
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid argument type: %s", arg.TypeName())
|
|
||||||
}
|
|
||||||
switch arg := args[1].(type) {
|
|
||||||
case *objects.Int:
|
|
||||||
arg1 = float64(arg.Value)
|
|
||||||
case *objects.Float:
|
|
||||||
arg1 = arg.Value
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid argument type: %s", arg.TypeName())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &objects.Float{Value: fn(arg0, arg1)}, nil
|
f2, ok := objects.ToFloat64(args[1])
|
||||||
|
if !ok {
|
||||||
|
return nil, objects.ErrInvalidTypeConversion
|
||||||
|
}
|
||||||
|
|
||||||
|
return &objects.Float{Value: fn(i1, f2)}, nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,27 +167,17 @@ func FuncAFIRF(fn func(float64, int) float64) *objects.UserFunction {
|
||||||
return nil, objects.ErrWrongNumArguments
|
return nil, objects.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
var arg0 float64
|
f1, ok := objects.ToFloat64(args[0])
|
||||||
var arg1 int
|
if !ok {
|
||||||
|
return nil, objects.ErrInvalidTypeConversion
|
||||||
switch arg := args[0].(type) {
|
|
||||||
case *objects.Int:
|
|
||||||
arg0 = float64(arg.Value)
|
|
||||||
case *objects.Float:
|
|
||||||
arg0 = float64(arg.Value)
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid argument type: %s", arg.TypeName())
|
|
||||||
}
|
|
||||||
switch arg := args[1].(type) {
|
|
||||||
case *objects.Int:
|
|
||||||
arg1 = int(arg.Value)
|
|
||||||
case *objects.Float:
|
|
||||||
arg1 = int(arg.Value)
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid argument type: %s", arg.TypeName())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &objects.Float{Value: fn(arg0, arg1)}, nil
|
i2, ok := objects.ToInt(args[1])
|
||||||
|
if !ok {
|
||||||
|
return nil, objects.ErrInvalidTypeConversion
|
||||||
|
}
|
||||||
|
|
||||||
|
return &objects.Float{Value: fn(f1, i2)}, nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,27 +191,17 @@ func FuncAFIRB(fn func(float64, int) bool) *objects.UserFunction {
|
||||||
return nil, objects.ErrWrongNumArguments
|
return nil, objects.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
var arg0 float64
|
f1, ok := objects.ToFloat64(args[0])
|
||||||
var arg1 int
|
if !ok {
|
||||||
|
return nil, objects.ErrInvalidTypeConversion
|
||||||
switch arg := args[0].(type) {
|
|
||||||
case *objects.Int:
|
|
||||||
arg0 = float64(arg.Value)
|
|
||||||
case *objects.Float:
|
|
||||||
arg0 = arg.Value
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid argument type: %s", arg.TypeName())
|
|
||||||
}
|
|
||||||
switch arg := args[1].(type) {
|
|
||||||
case *objects.Int:
|
|
||||||
arg1 = int(arg.Value)
|
|
||||||
case *objects.Float:
|
|
||||||
arg1 = int(arg.Value)
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid argument type: %s", arg.TypeName())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &objects.Bool{Value: fn(arg0, arg1)}, nil
|
i2, ok := objects.ToInt(args[1])
|
||||||
|
if !ok {
|
||||||
|
return nil, objects.ErrInvalidTypeConversion
|
||||||
|
}
|
||||||
|
|
||||||
|
return &objects.Bool{Value: fn(f1, i2)}, nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,17 +215,31 @@ func FuncAFRB(fn func(float64) bool) *objects.UserFunction {
|
||||||
return nil, objects.ErrWrongNumArguments
|
return nil, objects.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
var arg0 float64
|
f1, ok := objects.ToFloat64(args[0])
|
||||||
switch arg := args[0].(type) {
|
if !ok {
|
||||||
case *objects.Int:
|
return nil, objects.ErrInvalidTypeConversion
|
||||||
arg0 = float64(arg.Value)
|
|
||||||
case *objects.Float:
|
|
||||||
arg0 = arg.Value
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid argument type: %s", arg.TypeName())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &objects.Bool{Value: fn(arg0)}, nil
|
return &objects.Bool{Value: fn(f1)}, 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 {
|
||||||
|
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 wrapError(fn(s1)), nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
103
compiler/stdmods/os.go
Normal file
103
compiler/stdmods/os.go
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
package stdmods
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/d5/tengo/objects"
|
||||||
|
)
|
||||||
|
|
||||||
|
var osModule = map[string]objects.Object{
|
||||||
|
"o_rdonly": &objects.Int{Value: int64(os.O_RDONLY)},
|
||||||
|
"o_wronly": &objects.Int{Value: int64(os.O_WRONLY)},
|
||||||
|
"o_rdwr": &objects.Int{Value: int64(os.O_RDWR)},
|
||||||
|
"o_append": &objects.Int{Value: int64(os.O_APPEND)},
|
||||||
|
"o_create": &objects.Int{Value: int64(os.O_CREATE)},
|
||||||
|
"o_excl": &objects.Int{Value: int64(os.O_EXCL)},
|
||||||
|
"o_sync": &objects.Int{Value: int64(os.O_SYNC)},
|
||||||
|
"o_trunc": &objects.Int{Value: int64(os.O_TRUNC)},
|
||||||
|
|
||||||
|
"mode_dir": &objects.Int{Value: int64(os.ModeDir)},
|
||||||
|
"mode_append": &objects.Int{Value: int64(os.ModeAppend)},
|
||||||
|
"mode_exclusive": &objects.Int{Value: int64(os.ModeExclusive)},
|
||||||
|
"mode_temporary": &objects.Int{Value: int64(os.ModeTemporary)},
|
||||||
|
"mode_symlink": &objects.Int{Value: int64(os.ModeSymlink)},
|
||||||
|
"mode_device": &objects.Int{Value: int64(os.ModeDevice)},
|
||||||
|
"mode_named_pipe": &objects.Int{Value: int64(os.ModeNamedPipe)},
|
||||||
|
"mode_socket": &objects.Int{Value: int64(os.ModeSocket)},
|
||||||
|
"mode_setuid": &objects.Int{Value: int64(os.ModeSetuid)},
|
||||||
|
"mode_setgui": &objects.Int{Value: int64(os.ModeSetgid)},
|
||||||
|
"mode_char_device": &objects.Int{Value: int64(os.ModeCharDevice)},
|
||||||
|
"mode_sticky": &objects.Int{Value: int64(os.ModeSticky)},
|
||||||
|
"mode_irregular": &objects.Int{Value: int64(os.ModeIrregular)},
|
||||||
|
"mode_type": &objects.Int{Value: int64(os.ModeType)},
|
||||||
|
"mode_perm": &objects.Int{Value: int64(os.ModePerm)},
|
||||||
|
|
||||||
|
"path_separator": &objects.Char{Value: os.PathSeparator},
|
||||||
|
"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),
|
||||||
|
|
||||||
|
// TODO: system errors
|
||||||
|
//"err_invalid": &objects.Error{Value: os.ErrInvalid.Error()},
|
||||||
|
// TODO: STDIN, STDOUT, STDERR
|
||||||
|
// "stdin": nil,
|
||||||
|
// "stdout": nil,
|
||||||
|
// "stderr": nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
func osArgs(args ...objects.Object) (objects.Object, error) {
|
||||||
|
if len(args) != 0 {
|
||||||
|
return nil, objects.ErrWrongNumArguments
|
||||||
|
}
|
||||||
|
|
||||||
|
arr := &objects.Array{}
|
||||||
|
for _, osArg := range os.Args {
|
||||||
|
arr.Value = append(arr.Value, &objects.String{Value: osArg})
|
||||||
|
}
|
||||||
|
|
||||||
|
return arr, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func osChmod(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(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
|
||||||
|
}
|
|
@ -5,4 +5,5 @@ import "github.com/d5/tengo/objects"
|
||||||
// Modules contain the standard modules.
|
// Modules contain the standard modules.
|
||||||
var Modules = map[string]*objects.ModuleMap{
|
var Modules = map[string]*objects.ModuleMap{
|
||||||
"math": {Value: mathModule},
|
"math": {Value: mathModule},
|
||||||
|
"os": {Value: osModule},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue