From 5d2747e26f51cc2344a6bd95f93457248fdfebd8 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 29 Feb 2024 17:04:28 -0500 Subject: fin prob --- matrix-stdlib/src/core.rs | 298 ---------------------------------------------- 1 file changed, 298 deletions(-) delete mode 100644 matrix-stdlib/src/core.rs (limited to 'matrix-stdlib/src/core.rs') diff --git a/matrix-stdlib/src/core.rs b/matrix-stdlib/src/core.rs deleted file mode 100644 index 2c76497..0000000 --- a/matrix-stdlib/src/core.rs +++ /dev/null @@ -1,298 +0,0 @@ -use std::hash::{DefaultHasher, Hash, Hasher}; - -use matrix::{vm::Vm, value::Value, unpack_args, Result, unpack_varargs}; -use matrix_macros::native_func; -use rand::Rng; -use crate::{VmArgs, next, error}; - - -fn to_radix(r: i64, mut n: i64) -> String { - let mut result = String::new(); - let mut idx = 0; - if n == 0 { - result.push('0'); - return result - } else if n < 0 { - n = -n; - idx = 1; - result.push('-'); - } - while n != 0 { - let c = std::char::from_digit((n % r) as u32, r as u32).unwrap(); - result.insert(idx, c); - n /= r; - } - result -} - -#[native_func(1)] -fn bin(_: VmArgs, args: Vec) -> Result { - let [value] = unpack_args!(args); - match value { - Value::Int(n) => Ok(Value::String(to_radix(2, n).into())), - _ => error!("bin requires a integer agument") - } -} - -#[native_func(1)] -fn sex(_: VmArgs, args: Vec) -> Result { - let [value] = unpack_args!(args); - match value { - Value::Int(n) => Ok(Value::String(to_radix(6, n).into())), - _ => error!("sex requires a integer agument") - } -} - -#[native_func(1)] -fn oct(_: VmArgs, args: Vec) -> Result { - let [value] = unpack_args!(args); - match value { - Value::Int(n) => Ok(Value::String(to_radix(8, n).into())), - _ => error!("oct requires a integer agument") - } -} - -#[native_func(1)] -fn hex(_: VmArgs, args: Vec) -> Result { - let [value] = unpack_args!(args); - match value { - Value::Int(n) => Ok(Value::String(to_radix(16, n).into())), - _ => error!("hex requires a integer agument") - } -} - -#[native_func(2)] -fn radix(_: VmArgs, args: Vec) -> Result { - let [radix, value] = unpack_args!(args); - match (radix, value) { - (Value::Int(r), Value::Int(n)) => Ok(Value::String(to_radix(r, n).into())), - _ => error!("radix requires two integer aguments") - } -} - -#[native_func(1..)] -fn append(_: VmArgs, args: Vec) -> Result { - let ([list], args) = unpack_varargs!(args); - let Value::List(mut list) = list else { - return error!("append requires a list") - }; - for arg in args { - list.push(arg); - }; - Ok(Value::List(list)) -} - -#[native_func(2)] -fn push(_: VmArgs, args: Vec) -> Result { - let [list, value] = unpack_args!(args); - let Value::List(mut list) = list else { - return error!("push requires a list") - }; - list.push(value); - Ok(Value::List(list)) -} - -#[native_func(1)] -fn pop(_: VmArgs, args: Vec) -> Result { - let [list] = unpack_args!(args); - let Value::List(mut list) = list else { - return error!("pop requires a list") - }; - match list.pop() { - Some(v) => Ok(v), - None => Ok(Value::Nil) - } -} - -#[native_func(2)] -fn remove(_: VmArgs, args: Vec) -> Result { - let [list, index] = unpack_args!(args); - let Value::List(mut list) = list else { - return error!("remove requires a list") - }; - let Value::Int(i) = index else { - return error!("remove reuqires a int index"); - }; - if i < 0 || i as usize >= list.len() { - Ok(Value::Nil) - } else { - Ok(list.remove(i as usize)) - } -} - -#[native_func(1)] -fn hash(_: VmArgs, args: Vec) -> Result { - let [value] = unpack_args!(args); - if let Err(e) = value.can_hash() { - return Err(e) - }; - let mut hasher = DefaultHasher::new(); - value.hash(&mut hasher); - let fin = hasher.finish(); - Ok(Value::Int(fin as u32 as i64)) -} - -#[native_func(1)] -fn ord(_: VmArgs, args: Vec) -> Result { - let [value] = unpack_args!(args); - let Value::String(str) = value else { - return error!("ord requires a 1 length string") - }; - if str.len() != 1 { - return error!("ord requires a 1 length string") - } - let char = str.chars().next().unwrap(); - Ok(Value::Int(char as i64)) -} - -#[native_func(1)] -fn chr(_: VmArgs, args: Vec) -> Result { - let [value] = unpack_args!(args); - let Value::Int(i) = value else { - return error!("chr requires an int") - }; - match char::from_u32(i as u32) { - Some(c) => Ok(Value::String(String::from(c).into())), - None => error!("unable to get char from: {}", i as u32) - } -} - -#[native_func(1)] -fn str(_: VmArgs, args: Vec) -> Result { - let [value] = unpack_args!(args); - Ok(Value::String(format!("{value}").into())) -} - -fn partition(list: &mut [Value], lo: usize, hi: usize) -> (usize, usize) { - let pivot = list[(lo + hi) / 2].clone(); - let mut lt = lo; - let mut eq = lo; - let mut gt = hi; - - while eq <= gt { - if list[eq] < pivot { - list.swap(eq, lt); - lt += 1; - eq += 1; - } else if list[eq] > pivot { - list.swap(eq, gt); - gt -= 1; - } else { - eq += 1; - } - } - - (lt, gt) -} - -fn quicksort(list: &mut [Value], lo: usize, hi: usize) { - if lo < hi { - let (lt, gt) = partition(list, lo, hi); - if lt > 0 { - quicksort(list, lo, lt - 1); - } - quicksort(list, gt + 1, hi); - } -} - -#[native_func(1)] -fn sort(_: VmArgs, args: Vec) -> Result { - let [value] = unpack_args!(args); - let Value::List(mut list) = value else { - return error!("sort requires a list") - }; - let hi = list.len() - 1; - quicksort(list.as_mut(), 0, hi); - Ok(Value::List(list)) -} - -#[native_func(0)] -fn rand(_: VmArgs, _: Vec) -> Result { - let mut rng = rand::thread_rng(); - Ok(Value::Float(rng.gen())) -} - -#[native_func(0..)] -fn rand_range(_: VmArgs, args: Vec) -> Result { - use Value as V; - let ([], varargs) = unpack_varargs!(args); - let (min, max, step) = match varargs.as_slice() { - [V::Int(max)] => { - (0, *max, 1) - }, - [V::Int(min), V::Int(max)] => { - (*min, *max, 1) - }, - [V::Int(min), V::Int(max), V::Int(step)] => { - (*min, *max, *step) - }, - _ => return error!("rand_range takes 1 to 3 [Int]'s") - }; - if max <= min { - return Ok(Value::Int(min)) - } - let count = ((max - 1 - min) / step) + 1; - let rng = (rand::thread_rng().gen::() % (count as u32)) as i64; - let i = min + (rng * step); - Ok(Value::Int(i)) -} - -#[native_func(2)] -fn rand_int(_: VmArgs, args: Vec) -> Result { - use Value as V; - let (min, max) = match args.as_slice() { - [V::Int(min), V::Int(max)] => { - (*min, *max + 1) - }, - _ => return error!("rand_int takes 2 [Int]'s") - }; - if max <= min { - return Ok(Value::Int(min)) - } - - let count = max - min; - let rng = (rand::thread_rng().gen::() % (count as u32)) as i64; - let i = min + rng; - Ok(Value::Int(i)) -} - -#[native_func(1)] -fn rand_in((vm, frame): VmArgs, args: Vec) -> Result { - let [iter] = unpack_args!(args); - let iter = iter.into_iter_fn()?; - let mut vals = Vec::new(); - loop { - let val = next!(vm, frame, iter)?; - if val == Value::Nil { break } - vals.push(val); - } - if vals.is_empty() { - return Ok(Value::Nil) - } - let idx = rand::thread_rng().gen::() % vals.len(); - Ok(vals[idx].clone()) -} - -pub fn load(vm: &mut Vm) { - vm.load_global_fn(bin(), "bin"); - vm.load_global_fn(sex(), "sex"); - vm.load_global_fn(oct(), "oct"); - vm.load_global_fn(hex(), "hex"); - vm.load_global_fn(radix(), "radix"); - vm.load_global_fn(str(), "str"); - - vm.load_global_fn(append(), "append"); - vm.load_global_fn(push(), "push"); - vm.load_global_fn(pop(), "pop"); - vm.load_global_fn(remove(), "remove"); - - vm.load_global_fn(hash(), "hash"); - vm.load_global_fn(ord(), "ord"); - vm.load_global_fn(chr(), "chr"); - - vm.load_global_fn(sort(), "sort"); - vm.load_global_fn(rand(), "rand"); - vm.load_global_fn(rand_range(), "rand_range"); - vm.load_global_fn(rand_int(), "rand_int"); - vm.load_global_fn(rand_in(), "rand_in"); -} -- cgit v1.2.3-freya