Refactor random number generation to factory
- Use a `make-random` factory to create isolated random number generators. - Remove the global `prng` from the `Environment`. - Ensure `make-random` can be called with or without a seed.
This commit is contained in:
+31
-19
@@ -135,27 +135,39 @@ pub fn register(env: &Environment) {
|
||||
best
|
||||
});
|
||||
|
||||
// Random
|
||||
let random_ty = StaticType::Function(Box::new(Signature {
|
||||
// Random generator factory (Closure-based)
|
||||
let generator_sig = Signature {
|
||||
params: StaticType::Tuple(vec![]),
|
||||
ret: StaticType::Float,
|
||||
}));
|
||||
};
|
||||
|
||||
let make_random_ty = StaticType::FunctionOverloads(vec![
|
||||
Signature {
|
||||
params: StaticType::Tuple(vec![]),
|
||||
ret: StaticType::Function(Box::new(generator_sig.clone())),
|
||||
},
|
||||
Signature {
|
||||
params: StaticType::Tuple(vec![StaticType::Int]),
|
||||
ret: StaticType::Function(Box::new(generator_sig)),
|
||||
},
|
||||
]);
|
||||
|
||||
let prng = env.prng.clone();
|
||||
env.register_native_fn("random", random_ty, Purity::SideEffectFree, move |_| {
|
||||
Value::Float(prng.borrow_mut().f64())
|
||||
});
|
||||
|
||||
let seed_ty = StaticType::Function(Box::new(Signature {
|
||||
params: StaticType::Tuple(vec![StaticType::Int]),
|
||||
ret: StaticType::Void,
|
||||
}));
|
||||
|
||||
let prng_seed = env.prng.clone();
|
||||
env.register_native_fn("seed!", seed_ty, Purity::Impure, move |args| {
|
||||
if let Value::Int(s) = args[0] {
|
||||
prng_seed.borrow_mut().seed(s as u64);
|
||||
}
|
||||
Value::Void
|
||||
env.register_native_fn("make-random", make_random_ty, Purity::SideEffectFree, |args| {
|
||||
let rng = if args.is_empty() {
|
||||
fastrand::Rng::new()
|
||||
} else if let Value::Int(s) = args[0] {
|
||||
fastrand::Rng::with_seed(s as u64)
|
||||
} else {
|
||||
fastrand::Rng::new()
|
||||
};
|
||||
|
||||
let prng = std::rc::Rc::new(std::cell::RefCell::new(rng));
|
||||
|
||||
Value::Function(std::rc::Rc::new(crate::ast::types::NativeFunction {
|
||||
func: std::rc::Rc::new(move |_| {
|
||||
Value::Float(prng.borrow_mut().f64())
|
||||
}),
|
||||
purity: Purity::Impure,
|
||||
}))
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user