summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/d5/tengo/stdlib/rand.go
blob: 248d8e79f10ab6e1d8e3ee36600fdfe735c80794 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package stdlib

import (
	"math/rand"

	"github.com/d5/tengo/objects"
)

var randModule = map[string]objects.Object{
	"int":        &objects.UserFunction{Name: "int", Value: FuncARI64(rand.Int63)},
	"float":      &objects.UserFunction{Name: "float", Value: FuncARF(rand.Float64)},
	"intn":       &objects.UserFunction{Name: "intn", Value: FuncAI64RI64(rand.Int63n)},
	"exp_float":  &objects.UserFunction{Name: "exp_float", Value: FuncARF(rand.ExpFloat64)},
	"norm_float": &objects.UserFunction{Name: "norm_float", Value: FuncARF(rand.NormFloat64)},
	"perm":       &objects.UserFunction{Name: "perm", Value: FuncAIRIs(rand.Perm)},
	"seed":       &objects.UserFunction{Name: "seed", Value: FuncAI64R(rand.Seed)},
	"read": &objects.UserFunction{
		Value: func(args ...objects.Object) (ret objects.Object, err error) {
			if len(args) != 1 {
				return nil, objects.ErrWrongNumArguments
			}

			y1, ok := args[0].(*objects.Bytes)
			if !ok {
				return nil, objects.ErrInvalidArgumentType{
					Name:     "first",
					Expected: "bytes",
					Found:    args[0].TypeName(),
				}
			}

			res, err := rand.Read(y1.Value)
			if err != nil {
				ret = wrapError(err)
				return
			}

			return &objects.Int{Value: int64(res)}, nil
		},
	},
	"rand": &objects.UserFunction{
		Value: func(args ...objects.Object) (ret objects.Object, err error) {
			if len(args) != 1 {
				return nil, objects.ErrWrongNumArguments
			}

			i1, ok := objects.ToInt64(args[0])
			if !ok {
				return nil, objects.ErrInvalidArgumentType{
					Name:     "first",
					Expected: "int(compatible)",
					Found:    args[0].TypeName(),
				}
			}

			src := rand.NewSource(i1)

			return randRand(rand.New(src)), nil
		},
	},
}

func randRand(r *rand.Rand) *objects.ImmutableMap {
	return &objects.ImmutableMap{
		Value: map[string]objects.Object{
			"int":        &objects.UserFunction{Name: "int", Value: FuncARI64(r.Int63)},
			"float":      &objects.UserFunction{Name: "float", Value: FuncARF(r.Float64)},
			"intn":       &objects.UserFunction{Name: "intn", Value: FuncAI64RI64(r.Int63n)},
			"exp_float":  &objects.UserFunction{Name: "exp_float", Value: FuncARF(r.ExpFloat64)},
			"norm_float": &objects.UserFunction{Name: "norm_float", Value: FuncARF(r.NormFloat64)},
			"perm":       &objects.UserFunction{Name: "perm", Value: FuncAIRIs(r.Perm)},
			"seed":       &objects.UserFunction{Name: "seed", Value: FuncAI64R(r.Seed)},
			"read": &objects.UserFunction{
				Value: func(args ...objects.Object) (ret objects.Object, err error) {
					if len(args) != 1 {
						return nil, objects.ErrWrongNumArguments
					}

					y1, ok := args[0].(*objects.Bytes)
					if !ok {
						return nil, objects.ErrInvalidArgumentType{
							Name:     "first",
							Expected: "bytes",
							Found:    args[0].TypeName(),
						}
					}

					res, err := r.Read(y1.Value)
					if err != nil {
						ret = wrapError(err)
						return
					}

					return &objects.Int{Value: int64(res)}, nil
				},
			},
		},
	}
}