summaryrefslogtreecommitdiff
path: root/matrix-stdlib/src/core.rs
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-02-29 17:04:28 -0500
committerFreya Murphy <freya@freyacat.org>2024-02-29 17:04:28 -0500
commit5d2747e26f51cc2344a6bd95f93457248fdfebd8 (patch)
tree8755b4068166c3854d26817683ce438a771ab319 /matrix-stdlib/src/core.rs
parentmore mat, sys, and os stdlib functions, better matrix printing, other fixes (diff)
downloadmatrix-5d2747e26f51cc2344a6bd95f93457248fdfebd8.tar.gz
matrix-5d2747e26f51cc2344a6bd95f93457248fdfebd8.tar.bz2
matrix-5d2747e26f51cc2344a6bd95f93457248fdfebd8.zip
fin prob
Diffstat (limited to 'matrix-stdlib/src/core.rs')
-rw-r--r--matrix-stdlib/src/core.rs298
1 files changed, 0 insertions, 298 deletions
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<Value>) -> Result<Value> {
- 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<Value>) -> Result<Value> {
- 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<Value>) -> Result<Value> {
- 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<Value>) -> Result<Value> {
- 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<Value>) -> Result<Value> {
- 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<Value>) -> Result<Value> {
- 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<Value>) -> Result<Value> {
- 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<Value>) -> Result<Value> {
- 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<Value>) -> Result<Value> {
- 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<Value>) -> Result<Value> {
- 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<Value>) -> Result<Value> {
- 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<Value>) -> Result<Value> {
- 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<Value>) -> Result<Value> {
- 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<Value>) -> Result<Value> {
- 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<Value>) -> Result<Value> {
- let mut rng = rand::thread_rng();
- Ok(Value::Float(rng.gen()))
-}
-
-#[native_func(0..)]
-fn rand_range(_: VmArgs, args: Vec<Value>) -> Result<Value> {
- 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::<u32>() % (count as u32)) as i64;
- let i = min + (rng * step);
- Ok(Value::Int(i))
-}
-
-#[native_func(2)]
-fn rand_int(_: VmArgs, args: Vec<Value>) -> Result<Value> {
- 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::<u32>() % (count as u32)) as i64;
- let i = min + rng;
- Ok(Value::Int(i))
-}
-
-#[native_func(1)]
-fn rand_in((vm, frame): VmArgs, args: Vec<Value>) -> Result<Value> {
- 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::<usize>() % 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");
-}