forked from krka/kahlua2
/
RandomLib.java
94 lines (79 loc) · 2.88 KB
/
RandomLib.java
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
package se.krka.kahlua.stdlib;
import se.krka.kahlua.vm.*;
import java.util.Random;
public class RandomLib implements JavaFunction {
private static final Class RANDOM_CLASS = new Random().getClass();
private static final int RANDOM = 0;
private static final int RANDOMSEED = 1;
private static final int NEWRANDOM = 2;
private static final int NUM_FUNCTIONS = 3;
private static final String[] names;
private static final RandomLib[] functions;
static {
names = new String[NUM_FUNCTIONS];
names[RANDOM] = "random";
names[RANDOMSEED] = "seed";
names[NEWRANDOM] = "newrandom";
functions = new RandomLib[NUM_FUNCTIONS];
for (int i = 0; i < NUM_FUNCTIONS; i++) {
functions[i] = new RandomLib(i);
}
}
private static final RandomLib NEWRANDOM_FUN = new RandomLib(NEWRANDOM);
private final int index;
public RandomLib(int index) {
this.index = index;
}
public static void register(Platform platform, KahluaTable environment) {
KahluaTable t = platform.newTable();
for (int i = 0; i < NUM_FUNCTIONS - 1; i++) {
t.rawset(names[i], functions[i]);
}
t.rawset("__index", t);
KahluaTable metatables = KahluaUtil.getClassMetatables(platform, environment);
metatables.rawset(RANDOM_CLASS, t);
environment.rawset("newrandom", NEWRANDOM_FUN);
}
public int call(LuaCallFrame callFrame, int nArguments) {
switch (index) {
case RANDOM: return random(callFrame, nArguments);
case RANDOMSEED: return randomSeed(callFrame, nArguments);
case NEWRANDOM: return newRandom(callFrame);
}
return 0;
}
private int randomSeed(LuaCallFrame callFrame, int nArguments) {
Random random = getRandom(callFrame, "seed");
Object o = callFrame.get(1);
int hashCode = o == null ? 0 : o.hashCode();
random.setSeed(hashCode);
return 0;
}
private int random(LuaCallFrame callFrame, int nArguments) {
Random random = getRandom(callFrame, "random");
Double min = KahluaUtil.getOptionalNumberArg(callFrame, 2);
Double max = KahluaUtil.getOptionalNumberArg(callFrame, 3);
if (min == null) {
return callFrame.push(KahluaUtil.toDouble(random.nextDouble()));
}
int m = min.intValue();
int n;
if (max == null) {
n = m;
m = 1;
} else {
n = max.intValue();
}
return callFrame.push(KahluaUtil.toDouble(m + random.nextInt(n - m + 1)));
}
private Random getRandom(LuaCallFrame callFrame, String name) {
Object obj = KahluaUtil.getArg(callFrame, 1, name);
if (!(obj instanceof Random)) {
KahluaUtil.fail("First argument to " + name + " must be an object of type random.");
}
return (Random) obj;
}
private int newRandom(LuaCallFrame callFrame) {
return callFrame.push(new Random());
}
}