rand.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package stdlib
  2. import (
  3. "math/rand"
  4. "github.com/d5/tengo/v2"
  5. )
  6. var randModule = map[string]tengo.Object{
  7. "int": &tengo.UserFunction{
  8. Name: "int",
  9. Value: FuncARI64(rand.Int63),
  10. },
  11. "float": &tengo.UserFunction{
  12. Name: "float",
  13. Value: FuncARF(rand.Float64),
  14. },
  15. "intn": &tengo.UserFunction{
  16. Name: "intn",
  17. Value: FuncAI64RI64(rand.Int63n),
  18. },
  19. "exp_float": &tengo.UserFunction{
  20. Name: "exp_float",
  21. Value: FuncARF(rand.ExpFloat64),
  22. },
  23. "norm_float": &tengo.UserFunction{
  24. Name: "norm_float",
  25. Value: FuncARF(rand.NormFloat64),
  26. },
  27. "perm": &tengo.UserFunction{
  28. Name: "perm",
  29. Value: FuncAIRIs(rand.Perm),
  30. },
  31. "seed": &tengo.UserFunction{
  32. Name: "seed",
  33. Value: FuncAI64R(rand.Seed),
  34. },
  35. "read": &tengo.UserFunction{
  36. Name: "read",
  37. Value: func(args ...tengo.Object) (ret tengo.Object, err error) {
  38. if len(args) != 1 {
  39. return nil, tengo.ErrWrongNumArguments
  40. }
  41. y1, ok := args[0].(*tengo.Bytes)
  42. if !ok {
  43. return nil, tengo.ErrInvalidArgumentType{
  44. Name: "first",
  45. Expected: "bytes",
  46. Found: args[0].TypeName(),
  47. }
  48. }
  49. res, err := rand.Read(y1.Value)
  50. if err != nil {
  51. ret = wrapError(err)
  52. return
  53. }
  54. return tengo.Int{Value: int64(res)}, nil
  55. },
  56. },
  57. "rand": &tengo.UserFunction{
  58. Name: "rand",
  59. Value: func(args ...tengo.Object) (tengo.Object, error) {
  60. if len(args) != 1 {
  61. return nil, tengo.ErrWrongNumArguments
  62. }
  63. i1, ok := tengo.ToInt64(args[0])
  64. if !ok {
  65. return nil, tengo.ErrInvalidArgumentType{
  66. Name: "first",
  67. Expected: "int(compatible)",
  68. Found: args[0].TypeName(),
  69. }
  70. }
  71. src := rand.NewSource(i1)
  72. return randRand(rand.New(src)), nil
  73. },
  74. },
  75. }
  76. func randRand(r *rand.Rand) *tengo.ImmutableMap {
  77. return &tengo.ImmutableMap{
  78. Value: map[string]tengo.Object{
  79. "int": &tengo.UserFunction{
  80. Name: "int",
  81. Value: FuncARI64(r.Int63),
  82. },
  83. "float": &tengo.UserFunction{
  84. Name: "float",
  85. Value: FuncARF(r.Float64),
  86. },
  87. "intn": &tengo.UserFunction{
  88. Name: "intn",
  89. Value: FuncAI64RI64(r.Int63n),
  90. },
  91. "exp_float": &tengo.UserFunction{
  92. Name: "exp_float",
  93. Value: FuncARF(r.ExpFloat64),
  94. },
  95. "norm_float": &tengo.UserFunction{
  96. Name: "norm_float",
  97. Value: FuncARF(r.NormFloat64),
  98. },
  99. "perm": &tengo.UserFunction{
  100. Name: "perm",
  101. Value: FuncAIRIs(r.Perm),
  102. },
  103. "seed": &tengo.UserFunction{
  104. Name: "seed",
  105. Value: FuncAI64R(r.Seed),
  106. },
  107. "read": &tengo.UserFunction{
  108. Name: "read",
  109. Value: func(args ...tengo.Object) (
  110. ret tengo.Object,
  111. err error,
  112. ) {
  113. if len(args) != 1 {
  114. return nil, tengo.ErrWrongNumArguments
  115. }
  116. y1, ok := args[0].(*tengo.Bytes)
  117. if !ok {
  118. return nil, tengo.ErrInvalidArgumentType{
  119. Name: "first",
  120. Expected: "bytes",
  121. Found: args[0].TypeName(),
  122. }
  123. }
  124. res, err := r.Read(y1.Value)
  125. if err != nil {
  126. ret = wrapError(err)
  127. return
  128. }
  129. return tengo.Int{Value: int64(res)}, nil
  130. },
  131. },
  132. },
  133. }
  134. }