1 21 22 package org.armedbear.lisp; 23 24 import java.io.File ; 25 import java.io.FileInputStream ; 26 import java.io.FileOutputStream ; 27 import java.io.ObjectInputStream ; 28 import java.io.ObjectOutputStream ; 29 import java.math.BigInteger ; 30 import java.util.Random ; 31 32 public final class RandomState extends LispObject 33 { 34 private Random random; 35 36 public RandomState() 37 { 38 random = new Random (); 39 } 40 41 public RandomState(RandomState rs) throws ConditionThrowable 42 { 43 try { 44 File file = File.createTempFile("MAKE-RANDOM-STATE", null); 45 FileOutputStream fileOut = new FileOutputStream (file); 46 ObjectOutputStream out = new ObjectOutputStream (fileOut); 47 out.writeObject(rs.random); 48 out.close(); 49 FileInputStream fileIn = new FileInputStream (file); 50 ObjectInputStream in = new ObjectInputStream (fileIn); 51 random = (Random ) in.readObject(); 52 in.close(); 53 file.delete(); 54 } 55 catch (Throwable t) { 56 signal(new LispError("Unable to copy random state.")); 57 } 58 } 59 60 public LispObject typeOf() 61 { 62 return Symbol.RANDOM_STATE; 63 } 64 65 public LispClass classOf() 66 { 67 return BuiltInClass.RANDOM_STATE; 68 } 69 70 public LispObject typep(LispObject type) throws ConditionThrowable 71 { 72 if (type == Symbol.RANDOM_STATE) 73 return T; 74 if (type == BuiltInClass.RANDOM_STATE) 75 return T; 76 return super.typep(type); 77 } 78 79 public String writeToString() 80 { 81 return unreadableString("RANDOM-STATE"); 82 } 83 84 public LispObject random(LispObject arg) throws ConditionThrowable 85 { 86 if (arg instanceof Fixnum) { 87 int limit = ((Fixnum)arg).getValue(); 88 if (limit > 0) { 89 int n = random.nextInt((int)limit); 90 return new Fixnum(n); 91 } 92 } else if (arg instanceof Bignum) { 93 BigInteger limit = ((Bignum)arg).getValue(); 94 if (limit.signum() > 0) { 95 int bitLength = limit.bitLength(); 96 BigInteger rand = new BigInteger (bitLength + 1, random); 97 BigInteger remainder = rand.remainder(limit); 98 return number(remainder); 99 } 100 } else if (arg instanceof LispFloat) { 101 double limit = ((LispFloat)arg).getValue(); 102 if (limit > 0) { 103 double rand = random.nextDouble(); 104 return new LispFloat(rand * limit); 105 } 106 } 107 return signal(new TypeError(arg, "positive integer or positive float")); 108 } 109 110 private static final Primitive RANDOM = 113 new Primitive("random", "limit &optional random-state") 114 { 115 public LispObject execute(LispObject arg) throws ConditionThrowable 116 { 117 RandomState randomState = 118 (RandomState) _RANDOM_STATE_.symbolValueNoThrow(); 119 return randomState.random(arg); 120 } 121 public LispObject execute(LispObject first, LispObject second) 122 throws ConditionThrowable 123 { 124 if (second instanceof RandomState) { 125 RandomState randomState = (RandomState) second; 126 return randomState.random(first); 127 } 128 return signal(new TypeError(first, Symbol.RANDOM_STATE)); 129 } 130 }; 131 132 private static final Primitive MAKE_RANDOM_STATE = 135 new Primitive("make-random-state", "&optional state") { 136 public LispObject execute() throws ConditionThrowable 137 { 138 return new RandomState((RandomState)_RANDOM_STATE_.symbolValueNoThrow()); 139 } 140 public LispObject execute(LispObject arg) 141 throws ConditionThrowable 142 { 143 if (arg == NIL) 144 return new RandomState((RandomState)_RANDOM_STATE_.symbolValueNoThrow()); 145 if (arg == T) 146 return new RandomState(); 147 if (arg instanceof RandomState) 148 return new RandomState((RandomState)arg); 149 return signal(new TypeError(arg, Symbol.RANDOM_STATE)); 150 } 151 }; 152 153 private static final Primitive1 RANDOM_STATE_P = 155 new Primitive1("random-state-p", "object") 156 { 157 public LispObject execute(LispObject arg) 158 { 159 return arg instanceof RandomState ? T : NIL; 160 } 161 }; 162 } 163 | Popular Tags |