Revert "Revert "Made use of ::= in core libraries and defined a RebindError condition...
[cslatevm.git] / src / lib / random.slate
blob34e1f2910c463c408aa6779a6b936da4099b57d9
1 streams addPrototype: #RandomStream derivedFrom: {PositionableReadStream}.
2 "Answers a series of pseudo-random positive SmallIntegers across the entire
3 value range. It is very fast and has an extremely long period (2^19937-1).
4 Based off the Mersenne Twister code in C at:
5  http://www.math.keio.ac.jp/~matumoto/emt.html"
6 RandomStream addSlot: #state valued: (Array newSize: 624).
7 "This array is used for the calculations and works as a kind of history buffer.
8 The particular size of the array corresponds to / is determined by the
9 desired range of the outputs. See the website for particulars when porting."
11 rs@(RandomStream traits) collectionType
13   rs state
16 rs@(RandomStream traits) newSeed: seed
17 [(rs clone `setting: #{#state. #readLimit}
18      to: {rs state newSameSize. rs state size}) `>> [seed := seed. ]].
20 rs@(RandomStream traits) new
21 [rs newSeed: lobby ticksSinceEpoch].
23 rs@(RandomStream traits) next
24 [| tmp pos |
25   (pos := rs position) >= rs readLimit ifTrue: 
26     [rs refill.
27      pos := 0].
28   rs position := pos + 1.
29   (tmp := rs state at: pos)
30     bitXor:
31       ((tmp bitShift: -11)
32          bitXor:
33            (((tmp bitShift: 7) bitAnd: 16r9D2C5680)
34               bitXor:
35                 (((tmp bitShift: 15) bitAnd: 16rEFC60000)
36                    bitXor:
37                      (tmp bitShift: -18))))
40 rs@(RandomStream traits) seed: seed
41 [| state |
42   state := rs state.
43   seed := seed bitAnd: 16rFFFFFFFF.
44   state at: 0 := seed.
45   1 below: state size do:
46     [| :index |
47      seed := 69069 * seed bitAnd: 16rFFFFFFFF.
48      state at: index := seed].
49   rs position := rs readLimit
52 rs@(RandomStream traits) refill
53 [| state tmp |
54   state := rs state.
55   0 below: state size - 397
56     do: [| :index |
57          tmp :=
58            ((state at: index) bitAnd: 16r80000000)
59              bitOr:
60                ((state at: index + 1) bitAnd: 16r7FFFFFFF).
61          state at: index :=
62            (state at: index + 397)
63              bitXor:
64                ((tmp bitShift: -1)
65                   bitXor:
66                     ((16r100000000 - (tmp bitAnd: 1)) bitAnd: 16r9908B0DF))].
67   state size - 397 below: state size - 1 do:
68     [| :index |
69      tmp :=
70        ((state at: index) bitAnd: 16r80000000)
71          bitOr:
72            ((state at: index + 1) bitAnd: 16r7FFFFFFF).
73      state at: index :=
74        (state at: index + 397 - state size)
75          bitXor:
76            ((tmp bitShift: -1)
77               bitXor:
78                 ((16r100000000 - (tmp bitAnd: 1)) bitAnd: 16r9908B0DF))].
79   tmp :=
80     ((state at: 0) bitAnd: 16r80000000)
81       bitOr:
82         ((state at: 1) bitAnd: 16r7FFFFFFF).
83   state at: state size - 1 :=
84     (state at: 397 - 1)
85       bitXor:
86         ((tmp bitShift: -1)
87            bitXor:
88              ((16r100000000 - (tmp bitAnd: 1)) bitAnd: 16r9908B0DF)).
89   rs position := 0
92 SmallInteger traits addImmutableSlot: #Randomizer valued:
93   (RandomStream newSeed: Cloneable clone hash).
94 "TODO: seed with an actual random source, e.g. time values."
95 "TODO: make this non-global and yet persistable."
97 i@(SmallInteger traits) atRandom
99   i Randomizer next mod: i
102 i@(Integer traits) atRandom
104   i Randomizer next