xgo/stdlib/rand.go

139 lines
3 KiB
Go
Raw Normal View History

package stdlib
import (
"math/rand"
2019-12-30 00:38:51 +03:00
"github.com/d5/tengo/v2"
)
2019-12-20 22:40:38 +03:00
var randModule = map[string]tengo.Object{
"int": &tengo.UserFunction{
Name: "int",
Value: FuncARI64(rand.Int63),
},
"float": &tengo.UserFunction{
Name: "float",
Value: FuncARF(rand.Float64),
},
"intn": &tengo.UserFunction{
Name: "intn",
Value: FuncAI64RI64(rand.Int63n),
},
"exp_float": &tengo.UserFunction{
Name: "exp_float",
Value: FuncARF(rand.ExpFloat64),
},
"norm_float": &tengo.UserFunction{
Name: "norm_float",
Value: FuncARF(rand.NormFloat64),
},
"perm": &tengo.UserFunction{
Name: "perm",
Value: FuncAIRIs(rand.Perm),
},
"seed": &tengo.UserFunction{
Name: "seed",
Value: FuncAI64R(rand.Seed),
},
"read": &tengo.UserFunction{
Name: "read",
2019-12-20 22:40:38 +03:00
Value: func(args ...tengo.Object) (ret tengo.Object, err error) {
if len(args) != 1 {
2019-12-20 22:40:38 +03:00
return nil, tengo.ErrWrongNumArguments
}
2019-12-20 22:40:38 +03:00
y1, ok := args[0].(*tengo.Bytes)
if !ok {
2019-12-20 22:40:38 +03:00
return nil, tengo.ErrInvalidArgumentType{
Name: "first",
Expected: "bytes",
Found: args[0].TypeName(),
}
}
res, err := rand.Read(y1.Value)
if err != nil {
ret = wrapError(err)
return
}
2019-12-20 22:40:38 +03:00
return &tengo.Int{Value: int64(res)}, nil
},
},
2019-12-20 22:40:38 +03:00
"rand": &tengo.UserFunction{
Name: "rand",
2019-12-20 22:40:38 +03:00
Value: func(args ...tengo.Object) (tengo.Object, error) {
if len(args) != 1 {
2019-12-20 22:40:38 +03:00
return nil, tengo.ErrWrongNumArguments
}
2019-12-20 22:40:38 +03:00
i1, ok := tengo.ToInt64(args[0])
if !ok {
2019-12-20 22:40:38 +03:00
return nil, tengo.ErrInvalidArgumentType{
Name: "first",
Expected: "int(compatible)",
Found: args[0].TypeName(),
}
}
src := rand.NewSource(i1)
return randRand(rand.New(src)), nil
},
},
}
2019-12-20 22:40:38 +03:00
func randRand(r *rand.Rand) *tengo.ImmutableMap {
return &tengo.ImmutableMap{
Value: map[string]tengo.Object{
"int": &tengo.UserFunction{
Name: "int",
Value: FuncARI64(r.Int63),
},
"float": &tengo.UserFunction{
Name: "float",
Value: FuncARF(r.Float64),
},
"intn": &tengo.UserFunction{
Name: "intn",
Value: FuncAI64RI64(r.Int63n),
},
"exp_float": &tengo.UserFunction{
Name: "exp_float",
Value: FuncARF(r.ExpFloat64),
},
"norm_float": &tengo.UserFunction{
Name: "norm_float",
Value: FuncARF(r.NormFloat64),
},
"perm": &tengo.UserFunction{
Name: "perm",
Value: FuncAIRIs(r.Perm),
},
"seed": &tengo.UserFunction{
Name: "seed",
Value: FuncAI64R(r.Seed),
},
"read": &tengo.UserFunction{
Name: "read",
2019-12-20 22:40:38 +03:00
Value: func(args ...tengo.Object) (
ret tengo.Object,
err error,
) {
if len(args) != 1 {
2019-12-20 22:40:38 +03:00
return nil, tengo.ErrWrongNumArguments
}
2019-12-20 22:40:38 +03:00
y1, ok := args[0].(*tengo.Bytes)
if !ok {
2019-12-20 22:40:38 +03:00
return nil, tengo.ErrInvalidArgumentType{
Name: "first",
Expected: "bytes",
Found: args[0].TypeName(),
}
}
res, err := r.Read(y1.Value)
if err != nil {
ret = wrapError(err)
return
}
2019-12-20 22:40:38 +03:00
return &tengo.Int{Value: int64(res)}, nil
},
},
},
}
}