luaur_vm/functions/
math_random.rs1use crate::functions::lua_gettop::lua_gettop;
9use crate::functions::lua_l_checkinteger::lua_l_checkinteger;
10use crate::functions::lua_pushinteger::lua_pushinteger;
11use crate::functions::lua_pushnumber::lua_pushnumber;
12use crate::functions::pcg_32_random::pcg_32_random;
13use crate::macros::lua_l_argcheck::luaL_argcheck;
14use crate::macros::lua_l_error::luaL_error;
15use crate::type_aliases::lua_state::lua_State;
16
17pub unsafe fn math_random(L: *mut lua_State) -> i32 {
18 let g = (*L).global;
19 match lua_gettop(L) {
20 0 => {
21 let rl = pcg_32_random(&mut (*g).rngstate);
22 let rh = pcg_32_random(&mut (*g).rngstate);
23 let bits = (rl as u64) | ((rh as u64) << 32);
24 let rd = (bits as f64) * 2.0f64.powi(-64);
25 lua_pushnumber(L, rd);
26 }
27 1 => {
28 let u = lua_l_checkinteger(L, 1);
29 luaL_argcheck!(L, 1 <= u, 1, "interval is empty");
30
31 let x = (u as u64).wrapping_mul(pcg_32_random(&mut (*g).rngstate) as u64);
32 let r = (1 + (x >> 32)) as i32;
33 lua_pushinteger(L, r);
34 }
35 2 => {
36 let l = lua_l_checkinteger(L, 1);
37 let u = lua_l_checkinteger(L, 2);
38 luaL_argcheck!(L, l <= u, 2, "interval is empty");
39
40 let ul = (u as u32).wrapping_sub(l as u32);
41 luaL_argcheck!(L, ul < u32::MAX, 2, "interval is too large");
42 let x = (ul as u64 + 1).wrapping_mul(pcg_32_random(&mut (*g).rngstate) as u64);
43 let r = (l as i64 + (x >> 32) as i64) as i32;
44 lua_pushinteger(L, r);
45 }
46 _ => {
47 luaL_error!(L, "wrong number of arguments");
48 }
49 }
50 1
51}