atlas_vm 0.5.2

The Atlas77 Virtual Machine
Documentation
use crate::errors::RuntimeError;
use crate::memory::vm_data::VMData;
use crate::runtime::vm_state::VMState;
use crate::CallBack;
use rand::{thread_rng, Rng};

pub const MATH_FUNCTIONS: [(&str, CallBack); 7] = [
    ("abs", abs),
    ("pow", pow),
    ("sqrt", sqrt),
    ("min", min),
    ("max", max),
    ("round", round),
    ("random", random),
];

pub fn abs(state: VMState) -> Result<VMData, RuntimeError> {
    let val = state.stack.pop_with_rc(state.object_map)?.as_i64();
    Ok(VMData::new_i64(val.abs()))
}

pub fn pow(state: VMState) -> Result<VMData, RuntimeError> {
    let exponent = state.stack.pop_with_rc(state.object_map)?.as_i64();
    let base = state.stack.pop_with_rc(state.object_map)?.as_i64();
    Ok(VMData::new_i64(base.pow(exponent as u32)))
}

pub fn sqrt(state: VMState) -> Result<VMData, RuntimeError> {
    let val = state.stack.pop_with_rc(state.object_map)?.as_f64();
    Ok(VMData::new_f64(val.sqrt()))
}

pub fn min(state: VMState) -> Result<VMData, RuntimeError> {
    let v1 = state.stack.pop_with_rc(state.object_map)?.as_i64();
    let v2 = state.stack.pop_with_rc(state.object_map)?.as_i64();
    Ok(VMData::new_i64(std::cmp::min(v1, v2)))
}

pub fn max(state: VMState) -> Result<VMData, RuntimeError> {
    let v1 = state.stack.pop_with_rc(state.object_map)?.as_i64();
    let v2 = state.stack.pop_with_rc(state.object_map)?.as_i64();
    Ok(VMData::new_i64(std::cmp::max(v1, v2)))
}

pub fn round(state: VMState) -> Result<VMData, RuntimeError> {
    let val = state.stack.pop_with_rc(state.object_map)?.as_f64();
    Ok(VMData::new_i64(val.round() as i64))
}

pub fn random(state: VMState) -> Result<VMData, RuntimeError> {
    let range = (state.stack.pop_with_rc(state.object_map)?.as_i64(), state.stack.pop_with_rc(state.object_map)?.as_i64());
    let mut rng = thread_rng();
    let random = rng.gen_range(range.1..range.0);
    Ok(VMData::new_i64(random))
}