math-mumu 0.2.0-rc.4

Math functions plugin for the MuMu / Lava language
Documentation
use mumu::parser::types::{Value, FunctionValue};
use mumu::parser::interpreter::Interpreter;
use std::sync::{Arc, Mutex};

pub fn math_srand_bridge(
    _interp: &mut Interpreter,
    args: Vec<Value>
) -> Result<Value, String> {
    if args.len() != 1 {
        return Err(format!("math:srand => expected 1 argument (int/long/float seed), got {}", args.len()));
    }

    let seed = match &args[0] {
        Value::Int(i) => *i as u64,
        Value::Long(l) => *l as u64,
        Value::Float(f) => *f as u64,
        other => return Err(format!("math:srand => seed must be int/long/float, got {:?}", other)),
    };

    // Use Mutex for thread safety
    let rng = Arc::new(Mutex::new(SmallPrng::new(seed)));

    let closure_rng = rng.clone();
    let closure = move |_interp: &mut Interpreter, _args: Vec<Value>| {
        let mut rng = closure_rng.lock().unwrap();
        let next = rng.next_u32();
        Ok(Value::Int(next as i32))
    };

    Ok(Value::Function(Box::new(FunctionValue::RustClosure(
        "math:srand".to_string(),
        Arc::new(Mutex::new(closure)),
        0,
    ))))
}

// Minimal xorshift PRNG for demonstration
struct SmallPrng {
    state: u64,
}

impl SmallPrng {
    fn new(seed: u64) -> Self {
        SmallPrng { state: seed | 1 }
    }
    fn next_u32(&mut self) -> u32 {
        // xorshift64
        let mut x = self.state;
        x ^= x << 13;
        x ^= x >> 7;
        x ^= x << 17;
        self.state = x;
        (x & 0xFFFF_FFFF) as u32
    }
}