|
25 | 25 | */
|
26 | 26 | package com.oracle.graal.python.builtins.modules;
|
27 | 27 |
|
28 |
| -import static com.oracle.graal.python.runtime.exception.PythonErrorType.SystemError; |
29 |
| - |
30 |
| -import java.math.BigDecimal; |
31 |
| -import java.math.BigInteger; |
32 | 28 | import java.util.List;
|
33 |
| -import java.util.Random; |
34 | 29 |
|
35 | 30 | import com.oracle.graal.python.builtins.Builtin;
|
36 | 31 | import com.oracle.graal.python.builtins.CoreFunctions;
|
37 | 32 | import com.oracle.graal.python.builtins.PythonBuiltins;
|
38 |
| -import com.oracle.graal.python.builtins.objects.PNone; |
39 |
| -import com.oracle.graal.python.builtins.objects.ints.PInt; |
40 |
| -import com.oracle.graal.python.builtins.objects.tuple.PTuple; |
| 33 | +import com.oracle.graal.python.builtins.objects.random.PRandom; |
| 34 | +import com.oracle.graal.python.builtins.objects.type.PythonClass; |
| 35 | +import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode; |
41 | 36 | import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
|
42 |
| -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; |
43 | 37 | import com.oracle.truffle.api.dsl.GenerateNodeFactory;
|
44 | 38 | import com.oracle.truffle.api.dsl.NodeFactory;
|
45 | 39 | import com.oracle.truffle.api.dsl.Specialization;
|
46 | 40 |
|
47 |
| -@CoreFunctions(defineModule = "random") |
| 41 | +@CoreFunctions(defineModule = "_random") |
48 | 42 | public class RandomModuleBuiltins extends PythonBuiltins {
|
49 | 43 |
|
50 | 44 | @Override
|
51 | 45 | protected List<? extends NodeFactory<? extends PythonBuiltinNode>> getNodeFactories() {
|
52 | 46 | return RandomModuleBuiltinsFactory.getFactories();
|
53 | 47 | }
|
54 | 48 |
|
55 |
| - // TODO: put the RNG into the context |
56 |
| - protected static java.util.Random javaRandom = new java.util.Random(); |
57 |
| - |
58 |
| - @Builtin(name = "seed", fixedNumOfArguments = 1) |
59 |
| - @GenerateNodeFactory |
60 |
| - public abstract static class SeedNode extends PythonBuiltinNode { |
61 |
| - |
62 |
| - @SuppressWarnings("unused") |
63 |
| - @Specialization |
64 |
| - @TruffleBoundary |
65 |
| - public PNone seed(PNone none) { |
66 |
| - javaRandom.setSeed(System.currentTimeMillis()); |
67 |
| - return PNone.NONE; |
68 |
| - } |
69 |
| - |
70 |
| - @Specialization |
71 |
| - public PNone seed(int inputSeed) { |
72 |
| - javaRandom.setSeed(inputSeed); |
73 |
| - return PNone.NONE; |
74 |
| - } |
75 |
| - |
76 |
| - @Specialization |
77 |
| - public PNone seed(PInt inputSeed) { |
78 |
| - javaRandom.setSeed(inputSeed.longValue()); |
79 |
| - return PNone.NONE; |
80 |
| - } |
81 |
| - |
82 |
| - @Specialization |
83 |
| - public PNone seed(double inputSeed) { |
84 |
| - javaRandom.setSeed((long) ((Long.MAX_VALUE - inputSeed) * 412316924)); |
85 |
| - return PNone.NONE; |
86 |
| - } |
87 |
| - |
88 |
| - @Specialization |
89 |
| - @TruffleBoundary |
90 |
| - public PNone seed(Object inputSeed) { |
91 |
| - javaRandom.setSeed(System.identityHashCode(inputSeed)); |
92 |
| - return PNone.NONE; |
93 |
| - } |
94 |
| - } |
95 |
| - |
96 |
| - @Builtin(name = "jumpahead", fixedNumOfArguments = 1) |
97 |
| - @GenerateNodeFactory |
98 |
| - public abstract static class JumpAheadNode extends PythonBuiltinNode { |
99 |
| - @Specialization |
100 |
| - @TruffleBoundary |
101 |
| - public PNone jumpahead(int jumps) { |
102 |
| - for (int i = jumps; i > 0; i--) { |
103 |
| - javaRandom.nextInt(); |
104 |
| - } |
105 |
| - return PNone.NONE; |
106 |
| - } |
107 |
| - |
108 |
| - @Specialization |
109 |
| - @TruffleBoundary |
110 |
| - public PNone jumpahead(double jumps) { |
111 |
| - for (double i = jumps; i > 0; i--) { |
112 |
| - javaRandom.nextInt(); |
113 |
| - } |
114 |
| - return PNone.NONE; |
115 |
| - } |
116 |
| - } |
117 |
| - |
118 |
| - @Builtin(name = "setstate", fixedNumOfArguments = 1) |
119 |
| - @GenerateNodeFactory |
120 |
| - public abstract static class SetStateNode extends PythonBuiltinNode { |
121 |
| - |
122 |
| - @Specialization |
123 |
| - @TruffleBoundary |
124 |
| - public PNone setstate(PTuple tuple) { |
125 |
| - Object[] arr = tuple.getArray(); |
126 |
| - if (arr.length == 1) { |
127 |
| - Object object = arr[0]; |
128 |
| - if (object instanceof Long) { |
129 |
| - javaRandom = new Random((Long) object); |
130 |
| - return PNone.NONE; |
131 |
| - } |
132 |
| - } |
133 |
| - throw raise(SystemError, "state vector invalid."); |
134 |
| - } |
135 |
| - } |
136 |
| - |
137 |
| - // TODO: randrange is not part of _random |
138 |
| - @Builtin(name = "randrange", fixedNumOfArguments = 1) |
139 |
| - @GenerateNodeFactory |
140 |
| - public abstract static class RandRangeNode extends PythonBuiltinNode { |
141 |
| - |
142 |
| - @Specialization |
143 |
| - @TruffleBoundary |
144 |
| - public int randrange(int stop) { |
145 |
| - double scaled = javaRandom.nextDouble() * stop; |
146 |
| - |
147 |
| - while (scaled > stop) { |
148 |
| - scaled = javaRandom.nextDouble() * stop; |
149 |
| - } |
150 |
| - |
151 |
| - assert scaled <= stop; |
152 |
| - return (int) scaled; |
153 |
| - } |
154 |
| - |
155 |
| - @Specialization |
156 |
| - @TruffleBoundary |
157 |
| - public long randrange(long stop) { |
158 |
| - double scaled = javaRandom.nextDouble() * stop; |
159 |
| - |
160 |
| - while (scaled > stop) { |
161 |
| - scaled = javaRandom.nextDouble() * stop; |
162 |
| - } |
163 |
| - |
164 |
| - assert scaled <= stop; |
165 |
| - return (long) scaled; |
166 |
| - } |
167 |
| - |
168 |
| - @Specialization |
169 |
| - @TruffleBoundary |
170 |
| - public PInt randrange(PInt stop) { |
171 |
| - double stopDouble = stop.getValue().doubleValue(); |
172 |
| - |
173 |
| - double scaled = javaRandom.nextDouble() * stopDouble; |
174 |
| - |
175 |
| - while (scaled > stopDouble) { |
176 |
| - scaled = javaRandom.nextDouble() * stopDouble; |
177 |
| - } |
178 |
| - |
179 |
| - assert scaled <= stopDouble; |
180 |
| - return factory().createInt(BigDecimal.valueOf(scaled).toBigInteger()); |
181 |
| - } |
182 |
| - } |
183 |
| - |
184 |
| - @Builtin(name = "getstate", fixedNumOfArguments = 0) |
185 |
| - @GenerateNodeFactory |
186 |
| - public abstract static class GetStateNode extends PythonBuiltinNode { |
187 |
| - |
188 |
| - @SuppressWarnings("unused") |
189 |
| - @Specialization |
190 |
| - @TruffleBoundary |
191 |
| - public PTuple getstate(PNone none) { |
192 |
| - return factory().createTuple(new Object[]{javaRandom.nextLong()}); |
193 |
| - } |
194 |
| - } |
195 |
| - |
196 |
| - @Builtin(name = "random", fixedNumOfArguments = 0) |
197 |
| - @GenerateNodeFactory |
198 |
| - public abstract static class RandomNode extends PythonBuiltinNode { |
199 |
| - |
200 |
| - @Specialization |
201 |
| - @TruffleBoundary |
202 |
| - public double random() { |
203 |
| - return javaRandom.nextDouble(); |
204 |
| - } |
205 |
| - } |
206 |
| - |
207 |
| - @Builtin(name = "getrandbits", fixedNumOfArguments = 1) |
208 |
| - @GenerateNodeFactory |
209 |
| - public abstract static class GetRandBitsNode extends PythonBuiltinNode { |
210 |
| - |
211 |
| - @TruffleBoundary |
212 |
| - private static BigInteger createRandomBits(int k) { |
213 |
| - return new BigInteger(k, javaRandom); |
214 |
| - } |
215 |
| - |
216 |
| - @Specialization |
217 |
| - public PInt getrandbits(int k) { |
218 |
| - return factory().createInt(createRandomBits(k)); |
219 |
| - } |
220 |
| - } |
221 |
| - |
222 |
| - @Builtin(name = "randint", fixedNumOfArguments = 2) |
223 |
| - @GenerateNodeFactory |
224 |
| - public abstract static class RandIntNode extends PythonBuiltinNode { |
225 |
| - |
226 |
| - @Specialization |
227 |
| - @TruffleBoundary |
228 |
| - public int randint(int a, int b) { |
229 |
| - assert a <= b; |
230 |
| - return javaRandom.nextInt(b - a) + a; |
231 |
| - } |
232 |
| - } |
233 |
| - |
234 |
| - @Builtin(name = "uniform", fixedNumOfArguments = 2) |
| 49 | + // _random.Random([seed]) |
| 50 | + @Builtin(name = "Random", minNumOfArguments = 1, maxNumOfArguments = 2, constructsClass = PRandom.class) |
235 | 51 | @GenerateNodeFactory
|
236 |
| - public abstract static class UniformNode extends PythonBuiltinNode { |
| 52 | + abstract static class PRandomNode extends PythonBuiltinNode { |
| 53 | + @Child LookupAndCallBinaryNode setSeed = LookupAndCallBinaryNode.create("seed"); |
237 | 54 |
|
238 | 55 | @Specialization
|
239 |
| - @TruffleBoundary |
240 |
| - public double uniform(double a, double b) { |
241 |
| - assert a <= b; |
242 |
| - return (b - a) * javaRandom.nextDouble() + a; |
| 56 | + PRandom random(PythonClass cls, Object seed) { |
| 57 | + PRandom random = factory().createRandom(cls); |
| 58 | + setSeed.executeObject(random, seed); |
| 59 | + return random; |
243 | 60 | }
|
244 | 61 | }
|
245 |
| - |
246 | 62 | }
|
0 commit comments