diff --git a/mers_lib/src/program/configs/gen/function.rs b/mers_lib/src/program/configs/gen/function.rs index c5be0db..945d30d 100644 --- a/mers_lib/src/program/configs/gen/function.rs +++ b/mers_lib/src/program/configs/gen/function.rs @@ -66,7 +66,7 @@ pub trait StaticMersFunc: Sized + 'static + Send + Sync { } } -pub struct TwoFuncs(pub A, pub B); +pub struct Funcs(pub A, pub B); pub trait Func: Send + Sync + 'static { type I: FromMersData; @@ -138,7 +138,7 @@ impl StaticMersFunc for Box { } } -impl StaticMersFunc for TwoFuncs { +impl StaticMersFunc for Funcs { fn types() -> Vec<(Type, Type)> { let mut o = A::types(); for t in B::types() { diff --git a/mers_lib/src/program/configs/mod.rs b/mers_lib/src/program/configs/mod.rs index 8e24df7..274e8bb 100755 --- a/mers_lib/src/program/configs/mod.rs +++ b/mers_lib/src/program/configs/mod.rs @@ -1,7 +1,7 @@ use std::sync::{Arc, RwLock}; use crate::{ - data::{self, Data, Type}, + data::{self, Data, MersData, Type}, errors::CheckError, info::Local, program::run::CheckInfo, @@ -89,11 +89,15 @@ impl Config { } /// Add a variable. Its type will be that of the value stored in `val`. - pub fn add_var(self, name: String, val: Data) -> Self { - let t = val.get().as_type(); - self.add_var_arc(name, Arc::new(RwLock::new(val)), t) + pub fn add_var(self, name: impl Into, val: impl MersData) -> Self { + let t = val.as_type(); + self.add_var_from_arc(name.into(), Arc::new(RwLock::new(Data::new(val))), t) } - pub fn add_var_arc( + pub fn add_var_from_data(self, name: String, val: Data) -> Self { + let t = val.get().as_type(); + self.add_var_from_arc(name, Arc::new(RwLock::new(val)), t) + } + pub fn add_var_from_arc( mut self, name: String, val: Arc>, diff --git a/mers_lib/src/program/configs/with_base.rs b/mers_lib/src/program/configs/with_base.rs index d121110..e6bce21 100755 --- a/mers_lib/src/program/configs/with_base.rs +++ b/mers_lib/src/program/configs/with_base.rs @@ -27,7 +27,7 @@ impl Config { /// `lock_update: fn` locks the value of a reference so you can exclusively modify it: &var.lock_update(v -> (v, 1).sum) pub fn with_base(self) -> Self { self - .add_var("lock_update".to_string(), Data::new(data::function::Function { + .add_var("lock_update", data::function::Function { info: Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -74,8 +74,8 @@ impl Config { Ok(Data::empty_tuple()) }), inner_statements: None, - })) - .add_var("sleep".to_owned(), Data::new(func(|dur: OneOf, i| { + }) + .add_var("sleep", func(|dur: OneOf, i| { let mut sleep_dur = match dur { OneOf::A(dur) => Duration::from_secs(dur.max(0).try_into().unwrap_or(u64::MAX)), OneOf::B(dur) => Duration::from_secs_f64(dur.max(0.0)), @@ -86,16 +86,16 @@ impl Config { } std::thread::sleep(sleep_dur); Ok(()) - }))) - .add_var("exit".to_string(), Data::new(func_end(|code: isize, _| { + })) + .add_var("exit", func_end(|code: isize, _| { std::process::exit(code.try_into().unwrap_or(255)); - }))) - .add_var("panic".to_string(), Data::new(func_err(|message: &str, _| { + })) + .add_var("panic", func_err(|message: &str, _| { CheckError::from(message) - }))) + })) .add_var( - "len".to_string(), - Data::new(data::function::Function { + "len", + data::function::Function { info: Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -119,11 +119,11 @@ impl Config { }))) }), inner_statements: None, - }), + }, ) .add_var( - "eq".to_string(), - Data::new(data::function::Function { + "eq", + data::function::Function { info: Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -155,11 +155,11 @@ impl Config { }))) }), inner_statements: None, - }), + }, ) .add_var( - "mkref".to_string(), - Data::new(data::function::Function { + "mkref", + data::function::Function { info: Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| Ok(Type::new(data::reference::ReferenceT(a.clone()))))), @@ -167,11 +167,11 @@ impl Config { Ok(Data::new(data::reference::Reference(Arc::new(RwLock::new(a.clone()))))) }), inner_statements: None, - }), + }, ) .add_var( - "deref".to_string(), - Data::new(data::function::Function { + "deref", + data::function::Function { info: Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| if let Some(v) = a.dereference() { Ok(v) } else { Err(format!("cannot dereference type {a}").into()) @@ -188,7 +188,7 @@ impl Config { } }), inner_statements: None, - }), + }, ) } } diff --git a/mers_lib/src/program/configs/with_command_running.rs b/mers_lib/src/program/configs/with_command_running.rs index f97f3da..4f4cbee 100755 --- a/mers_lib/src/program/configs/with_command_running.rs +++ b/mers_lib/src/program/configs/with_command_running.rs @@ -25,8 +25,8 @@ impl Config { self .add_type("ChildProcess".to_owned(), Ok(Arc::new(Type::new(ChildProcessT)))) .add_var( - "run_command".to_string(), - Data::new(data::function::Function { + "run_command", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new( CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -77,11 +77,11 @@ impl Config { } }), inner_statements: None, - }), + }, ) .add_var( - "spawn_command".to_string(), - Data::new(data::function::Function { + "spawn_command", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new( CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -121,11 +121,11 @@ impl Config { } }), inner_statements: None, - }), + }, ) .add_var( - "childproc_exited".to_string(), - Data::new(data::function::Function { + "childproc_exited", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new( CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -149,11 +149,11 @@ impl Config { }) }), inner_statements: None, - }), + }, ) .add_var( - "childproc_await".to_string(), - Data::new(data::function::Function { + "childproc_await", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new( CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -182,11 +182,11 @@ impl Config { }) }), inner_statements: None, - }), + }, ) .add_var( - "childproc_write_bytes".to_string(), - Data::new(data::function::Function { + "childproc_write_bytes", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new( CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -211,11 +211,11 @@ impl Config { }) }), inner_statements: None, - }), + }, ) .add_var( - "childproc_write_string".to_string(), - Data::new(data::function::Function { + "childproc_write_string", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new( CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -240,11 +240,11 @@ impl Config { }) }), inner_statements: None, - }), + }, ) .add_var( - "childproc_read_byte".to_string(), - Data::new(data::function::Function { + "childproc_read_byte", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new( CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -269,11 +269,11 @@ impl Config { }) }), inner_statements: None, - }), + }, ) .add_var( - "childproc_readerr_byte".to_string(), - Data::new(data::function::Function { + "childproc_readerr_byte", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new( CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -298,11 +298,11 @@ impl Config { }) }), inner_statements: None, - }), + }, ) .add_var( - "childproc_read_line".to_string(), - Data::new(data::function::Function { + "childproc_read_line", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new( CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -327,11 +327,11 @@ impl Config { }) }), inner_statements: None, - }), + }, ) .add_var( - "childproc_readerr_line".to_string(), - Data::new(data::function::Function { + "childproc_readerr_line", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new( CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -356,7 +356,7 @@ impl Config { }) }), inner_statements: None, - }), + }, ) } } diff --git a/mers_lib/src/program/configs/with_get.rs b/mers_lib/src/program/configs/with_get.rs index 1a5a27a..a190d79 100755 --- a/mers_lib/src/program/configs/with_get.rs +++ b/mers_lib/src/program/configs/with_get.rs @@ -11,8 +11,8 @@ impl Config { /// `get: fn` is used to retrieve elements from collections pub fn with_get(self) -> Self { self.add_var( - "get".to_string(), - Data::new(data::function::Function { + "get", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -70,7 +70,7 @@ impl Config { } }), inner_statements: None, - }), + }, ) } } diff --git a/mers_lib/src/program/configs/with_iters.rs b/mers_lib/src/program/configs/with_iters.rs index 447c640..0f20044 100755 --- a/mers_lib/src/program/configs/with_iters.rs +++ b/mers_lib/src/program/configs/with_iters.rs @@ -28,25 +28,25 @@ impl Config { /// `all: fn` returns true if all elements of the iterator are true pub fn with_iters(self) -> Self { self - .add_var("any".to_string(), Data::new(genfunc_iter_in_val_out("all".to_string(), data::bool::BoolT, Type::new(data::bool::BoolT), |a, _i| { + .add_var("any", genfunc_iter_in_val_out("all".to_string(), data::bool::BoolT, Type::new(data::bool::BoolT), |a, _i| { for v in a.get().iterable().unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::().is_some_and(|v| v.0))) { if v? { return Ok(Data::new(data::bool::Bool(true))); } } Ok(Data::new(data::bool::Bool(false))) - }))) - .add_var("all".to_string(), Data::new(genfunc_iter_in_val_out("all".to_string(), data::bool::BoolT, Type::new(data::bool::BoolT), |a, _i| { + })) + .add_var("all", genfunc_iter_in_val_out("all".to_string(), data::bool::BoolT, Type::new(data::bool::BoolT), |a, _i| { for v in a.get().iterable().unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::().is_some_and(|v| v.0))) { if !v? { return Ok(Data::new(data::bool::Bool(false))); } } Ok(Data::new(data::bool::Bool(true))) - }))) + })) .add_var( - "for_each".to_string(), - Data::new(data::function::Function { + "for_each", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -107,30 +107,30 @@ impl Config { } }), inner_statements: None, - }), + }, ) .add_var( - "map".to_string(), - Data::new(genfunc_iter_and_func("map", ItersT::Map, Iters::Map)) + "map", + genfunc_iter_and_func("map", ItersT::Map, Iters::Map) ) .add_var( - "filter".to_string(), - Data::new(genfunc_iter_and_func("filter", ItersT::Filter, Iters::Filter)), + "filter", + genfunc_iter_and_func("filter", ItersT::Filter, Iters::Filter), ) .add_var( - "filter_map".to_string(), - Data::new(genfunc_iter_and_func("filter_map", ItersT::FilterMap, Iters::FilterMap)), + "filter_map", + genfunc_iter_and_func("filter_map", ItersT::FilterMap, Iters::FilterMap), ) .add_var( - "map_while".to_string(), - Data::new(genfunc_iter_and_func("map_while", ItersT::MapWhile, Iters::MapWhile)), + "map_while", + genfunc_iter_and_func("map_while", ItersT::MapWhile, Iters::MapWhile), ) - .add_var("take".to_string(), Data::new(genfunc_iter_and_arg("take", |_: &data::int::IntT| ItersT::Take, |v: &data::int::Int| { - Iters::Take(v.0.max(0) as _) - }, &data::int::IntT))) + .add_var("take", genfunc_iter_and_arg("take", |_: &data::int::IntT| ItersT::Take, |v: &data::int::Int| { + Iters::Take(v.0.max(0) as _) + }, &data::int::IntT)) .add_var( - "enumerate".to_string(), - Data::new(data::function::Function { + "enumerate", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -143,11 +143,11 @@ impl Config { })), run: Arc::new(|a, _i| Ok(Data::new(Iter(Iters::Enumerate, a.clone())))), inner_statements: None, - }), + }, ) .add_var( - "chain".to_string(), - Data::new(data::function::Function { + "chain", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -160,7 +160,7 @@ impl Config { })), run: Arc::new(|a, _i| Ok(Data::new(Iter(Iters::Chained, a.clone())))), inner_statements: None, - }), + }, ) } } diff --git a/mers_lib/src/program/configs/with_list.rs b/mers_lib/src/program/configs/with_list.rs index fb42ff5..6184717 100755 --- a/mers_lib/src/program/configs/with_list.rs +++ b/mers_lib/src/program/configs/with_list.rs @@ -31,7 +31,7 @@ impl Config { let srca = Arc::new(src.clone()); let t = crate::parsing::types::parse_type(&mut src, &srca)?; Ok(Arc::new(Type::new(ListT(crate::parsing::types::type_from_parsed(&t, i)?))))}))) - .add_var("get_mut".to_string(), Data::new(data::function::Function { + .add_var("get_mut", data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -97,10 +97,10 @@ impl Config { Ok(o) }), inner_statements: None, - })) + }) .add_var( - "pop".to_string(), - Data::new(data::function::Function { + "pop", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -144,11 +144,11 @@ impl Config { }) }), inner_statements: None, - }), + }, ) .add_var( - "push".to_string(), - Data::new(data::function::Function { + "push", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -207,11 +207,11 @@ impl Config { Ok(Data::empty_tuple()) }), inner_statements: None, - }), + }, ) .add_var( - "as_list".to_string(), - Data::new(data::function::Function { + "as_list", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -231,7 +231,7 @@ impl Config { } }), inner_statements: None, - }), + }, ) } } diff --git a/mers_lib/src/program/configs/with_math.rs b/mers_lib/src/program/configs/with_math.rs index db67944..1d54675 100755 --- a/mers_lib/src/program/configs/with_math.rs +++ b/mers_lib/src/program/configs/with_math.rs @@ -11,7 +11,7 @@ use crate::{ use super::{ gen::{ - function::{fun, func, StaticMersFunc, TwoFuncs}, + function::{fun, func, Funcs, StaticMersFunc}, OneOf, OneOrNone, }, Config, @@ -50,60 +50,60 @@ impl Config { /// `round_ties_even_to_int: fn` round ties (x.5) to the nearest even number, return the result as an Int (saturates at the Int boundaries, hence the to_int instead of as_int) pub fn with_math(self) -> Self { self.add_var( - "parse_float".to_owned(), - Data::new(func(|n: &str, _| Ok(OneOrNone(n.parse::().ok())))), + "parse_float", + func(|n: &str, _| Ok(OneOrNone(n.parse::().ok()))), ) .add_var( - "parse_int".to_owned(), - Data::new(func(|n: &str, _| Ok(OneOrNone(n.parse::().ok())))), + "parse_int", + func(|n: &str, _| Ok(OneOrNone(n.parse::().ok()))), ) .add_var( - "lt".to_string(), - Data::new(func(|v: (OneOf, OneOf), _| { + "lt", + func(|v: (OneOf, OneOf), _| { Ok(match v { (OneOf::A(a), OneOf::A(b)) => a < b, (OneOf::A(a), OneOf::B(b)) => (a as f64) < b, (OneOf::B(a), OneOf::A(b)) => a < (b as f64), (OneOf::B(a), OneOf::B(b)) => a < b, }) - })), + }), ) .add_var( - "gt".to_string(), - Data::new(func(|v: (OneOf, OneOf), _| { + "gt", + func(|v: (OneOf, OneOf), _| { Ok(match v { (OneOf::A(a), OneOf::A(b)) => a > b, (OneOf::A(a), OneOf::B(b)) => (a as f64) > b, (OneOf::B(a), OneOf::A(b)) => a > (b as f64), (OneOf::B(a), OneOf::B(b)) => a > b, }) - })), + }), ) .add_var( - "ltoe".to_string(), - Data::new(func(|v: (OneOf, OneOf), _| { + "ltoe", + func(|v: (OneOf, OneOf), _| { Ok(match v { (OneOf::A(a), OneOf::A(b)) => a <= b, (OneOf::A(a), OneOf::B(b)) => (a as f64) <= b, (OneOf::B(a), OneOf::A(b)) => a <= (b as f64), (OneOf::B(a), OneOf::B(b)) => a <= b, }) - })), + }), ) .add_var( - "gtoe".to_string(), - Data::new(func(|v: (OneOf, OneOf), _| { + "gtoe", + func(|v: (OneOf, OneOf), _| { Ok(match v { (OneOf::A(a), OneOf::A(b)) => a >= b, (OneOf::A(a), OneOf::B(b)) => (a as f64) >= b, (OneOf::B(a), OneOf::A(b)) => a >= (b as f64), (OneOf::B(a), OneOf::B(b)) => a >= b, }) - })), + }), ) .add_var( - "signum".to_string(), - Data::new(func(|n: OneOf, _| { + "signum", + func(|n: OneOf, _| { Ok(match n { OneOf::A(n) => n.signum(), OneOf::B(n) => { @@ -116,216 +116,192 @@ impl Config { } } }) - })), + }), ) .add_var( - "add".to_string(), - Data::new(num_iter_to_num("sum", Ok(0), |a, v| match (a, v) { + "add", + num_iter_to_num("sum", Ok(0), |a, v| match (a, v) { (Ok(a), Ok(v)) => Ok(a + v), (Ok(a), Err(v)) => Err(a as f64 + v), (Err(a), Ok(v)) => Err(a + v as f64), (Err(a), Err(v)) => Err(a + v), - })), + }), ) .add_var( - "sub".to_string(), - Data::new( - TwoFuncs( - fun(|(n, d): (isize, isize), _| Ok(n.wrapping_sub(d))), - fun(|(n, d): (OneOf, OneOf), _| { - let n = match n { - OneOf::A(v) => v as f64, - OneOf::B(v) => v, - }; - let d = match d { - OneOf::A(v) => v as f64, - OneOf::B(v) => v, - }; - Ok(n - d) - }), - ) - .mers_func(), - ), + "sub", + Funcs( + fun(|(n, d): (isize, isize), _| Ok(n.wrapping_sub(d))), + fun(|(n, d): (OneOf, OneOf), _| { + let n = match n { + OneOf::A(v) => v as f64, + OneOf::B(v) => v, + }; + let d = match d { + OneOf::A(v) => v as f64, + OneOf::B(v) => v, + }; + Ok(n - d) + }), + ) + .mers_func(), ) .add_var( - "mul".to_string(), - Data::new(num_iter_to_num("sum", Ok(1), |a, v| match (a, v) { + "mul", + num_iter_to_num("sum", Ok(1), |a, v| match (a, v) { (Ok(a), Ok(v)) => Ok(a * v), (Ok(a), Err(v)) => Err(a as f64 * v), (Err(a), Ok(v)) => Err(a * v as f64), (Err(a), Err(v)) => Err(a * v), - })), + }), ) .add_var( - "div".to_string(), - Data::new( - TwoFuncs( - fun(|(n, d): (isize, isize), _| { - n.checked_div(d) - .ok_or_else(|| CheckError::from("attempted to divide by zero")) - }), - fun(|(n, d): (OneOf, OneOf), _| { - let n = match n { - OneOf::A(v) => v as f64, - OneOf::B(v) => v, - }; - let d = match d { - OneOf::A(v) => v as f64, - OneOf::B(v) => v, - }; - Ok(n / d) - }), - ) - .mers_func(), - ), + "div", + Funcs( + fun(|(n, d): (isize, isize), _| { + n.checked_div(d) + .ok_or_else(|| CheckError::from("attempted to divide by zero")) + }), + fun(|(n, d): (OneOf, OneOf), _| { + let n = match n { + OneOf::A(v) => v as f64, + OneOf::B(v) => v, + }; + let d = match d { + OneOf::A(v) => v as f64, + OneOf::B(v) => v, + }; + Ok(n / d) + }), + ) + .mers_func(), ) .add_var( - "remainder".to_string(), - Data::new( - TwoFuncs( - fun(|(n, d): (isize, isize), _| { - n.checked_rem(d).ok_or_else(|| { - CheckError::from( - "attempted to calculate remainder with zero, or overflow occured", - ) - }) - }), - fun(|(n, d): (OneOf, OneOf), _| { - let n = match n { - OneOf::A(v) => v as f64, - OneOf::B(v) => v, - }; - let d = match d { - OneOf::A(v) => v as f64, - OneOf::B(v) => v, - }; - Ok(n.rem(d)) - }), - ) - .mers_func(), - ), + "remainder", + Funcs( + fun(|(n, d): (isize, isize), _| { + n.checked_rem(d).ok_or_else(|| { + CheckError::from( + "attempted to calculate remainder with zero, or overflow occured", + ) + }) + }), + fun(|(n, d): (OneOf, OneOf), _| { + let n = match n { + OneOf::A(v) => v as f64, + OneOf::B(v) => v, + }; + let d = match d { + OneOf::A(v) => v as f64, + OneOf::B(v) => v, + }; + Ok(n.rem(d)) + }), + ) + .mers_func(), ) .add_var( - "modulo".to_string(), - Data::new( - TwoFuncs( - fun(|(n, d): (isize, isize), _| { - n.checked_rem_euclid(d).ok_or_else(|| { - CheckError::from( - "attempted to perform modulo with zero, or overflow occured", - ) - }) - }), - fun(|(n, d): (OneOf, OneOf), _| { - let n = match n { - OneOf::A(v) => v as f64, - OneOf::B(v) => v, - }; - let d = match d { - OneOf::A(v) => v as f64, - OneOf::B(v) => v, - }; - Ok(n.rem_euclid(d)) - }), - ) - .mers_func(), - ), + "modulo", + Funcs( + fun(|(n, d): (isize, isize), _| { + n.checked_rem_euclid(d).ok_or_else(|| { + CheckError::from( + "attempted to perform modulo with zero, or overflow occured", + ) + }) + }), + fun(|(n, d): (OneOf, OneOf), _| { + let n = match n { + OneOf::A(v) => v as f64, + OneOf::B(v) => v, + }; + let d = match d { + OneOf::A(v) => v as f64, + OneOf::B(v) => v, + }; + Ok(n.rem_euclid(d)) + }), + ) + .mers_func(), ) .add_var( - "abs".to_string(), - Data::new( - TwoFuncs( - fun(|v: isize, _| Ok(v.saturating_abs())), - fun(|v: f64, _| Ok(v.abs())), - ) - .mers_func(), - ), + "abs", + Funcs( + fun(|v: isize, _| Ok(v.saturating_abs())), + fun(|v: f64, _| Ok(v.abs())), + ) + .mers_func(), ) .add_var( - "pow".to_string(), - Data::new( - TwoFuncs( - fun(|(l, r): (isize, isize), _| Ok(l.pow(r.try_into().unwrap_or(u32::MAX)))), - fun(|(l, r): (OneOf, OneOf), _| { - let l = match l { - OneOf::A(v) => v as f64, - OneOf::B(v) => v, - }; - Ok(match r { - OneOf::A(r) => { - if let Ok(r) = r.try_into() { - l.powi(r) - } else { - l.powf(r as f64) - } + "pow", + Funcs( + fun(|(l, r): (isize, isize), _| Ok(l.pow(r.try_into().unwrap_or(u32::MAX)))), + fun(|(l, r): (OneOf, OneOf), _| { + let l = match l { + OneOf::A(v) => v as f64, + OneOf::B(v) => v, + }; + Ok(match r { + OneOf::A(r) => { + if let Ok(r) = r.try_into() { + l.powi(r) + } else { + l.powf(r as f64) } - OneOf::B(r) => l.powf(r), - }) - }), - ) - .mers_func(), - ), + } + OneOf::B(r) => l.powf(r), + }) + }), + ) + .mers_func(), ) .add_var( - "as_float".to_owned(), - Data::new(func(|v: OneOf, _| { + "as_float", + func(|v: OneOf, _| { Ok(match v { OneOf::A(v) => v as f64, OneOf::B(v) => v, }) - })), + }), ) .add_var( - "round_as_float".to_owned(), - Data::new(func(|v: f64, _| -> Result { Ok(v.round()) })), + "round_as_float", + func(|v: f64, _| -> Result { Ok(v.round()) }), ) .add_var( - "ceil_as_float".to_owned(), - Data::new(func(|v: f64, _| -> Result { Ok(v.ceil()) })), + "ceil_as_float", + func(|v: f64, _| -> Result { Ok(v.ceil()) }), ) .add_var( - "floor_as_float".to_owned(), - Data::new(func(|v: f64, _| -> Result { Ok(v.floor()) })), + "floor_as_float", + func(|v: f64, _| -> Result { Ok(v.floor()) }), ) .add_var( - "truncate_as_float".to_owned(), - Data::new(func(|v: f64, _| -> Result { Ok(v.trunc()) })), + "truncate_as_float", + func(|v: f64, _| -> Result { Ok(v.trunc()) }), ) .add_var( - "round_ties_even_as_float".to_owned(), - Data::new(func(|v: f64, _| -> Result { - Ok(v.round_ties_even()) - })), + "round_ties_even_as_float", + func(|v: f64, _| -> Result { Ok(v.round_ties_even()) }), ) .add_var( - "round_to_int".to_owned(), - Data::new(func(|v: f64, _| -> Result { - Ok(isize_from(v.round())) - })), + "round_to_int", + func(|v: f64, _| -> Result { Ok(isize_from(v.round())) }), ) .add_var( - "ceil_to_int".to_owned(), - Data::new(func(|v: f64, _| -> Result { - Ok(isize_from(v.ceil())) - })), + "ceil_to_int", + func(|v: f64, _| -> Result { Ok(isize_from(v.ceil())) }), ) .add_var( - "floor_to_int".to_owned(), - Data::new(func(|v: f64, _| -> Result { - Ok(isize_from(v.floor())) - })), + "floor_to_int", + func(|v: f64, _| -> Result { Ok(isize_from(v.floor())) }), ) .add_var( - "truncate_to_int".to_owned(), - Data::new(func(|v: f64, _| -> Result { - Ok(isize_from(v.trunc())) - })), + "truncate_to_int", + func(|v: f64, _| -> Result { Ok(isize_from(v.trunc())) }), ) .add_var( "round_ties_even_to_int".to_owned(), - Data::new(func(|v: f64, _| -> Result { - Ok(isize_from(v.round_ties_even())) - })), + func(|v: f64, _| -> Result { Ok(isize_from(v.round_ties_even())) }), ) } } diff --git a/mers_lib/src/program/configs/with_multithreading.rs b/mers_lib/src/program/configs/with_multithreading.rs index 68ef6fb..6bd8eff 100755 --- a/mers_lib/src/program/configs/with_multithreading.rs +++ b/mers_lib/src/program/configs/with_multithreading.rs @@ -28,8 +28,8 @@ impl Config { })), ) .add_var( - "thread".to_string(), - Data::new(data::function::Function { + "thread", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -52,9 +52,9 @@ impl Config { ))))))) }), inner_statements: None, - }), + }, ) - .add_var("thread_finished".to_string(), Data::new(data::function::Function { + .add_var("thread_finished", data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -74,8 +74,8 @@ impl Config { }))) }), inner_statements: None, - })) - .add_var("thread_await".to_string(), Data::new(data::function::Function { + }) + .add_var("thread_await", data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -100,7 +100,7 @@ impl Config { d }), inner_statements: None, - })) + }) } } diff --git a/mers_lib/src/program/configs/with_stdio.rs b/mers_lib/src/program/configs/with_stdio.rs index fef043e..0bacb77 100755 --- a/mers_lib/src/program/configs/with_stdio.rs +++ b/mers_lib/src/program/configs/with_stdio.rs @@ -20,8 +20,8 @@ impl Config { /// `read_line: fn` reads a line from stdin and returns it pub fn with_stdio(self) -> Self { self.add_var( - "read_line".to_string(), - Data::new(data::function::Function { + "read_line", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { @@ -45,11 +45,11 @@ impl Config { }) }), inner_statements: None, - }), + }, ) .add_var( - "debug".to_string(), - Data::new(data::function::Function { + "debug", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| Ok(a.clone()))), @@ -60,11 +60,11 @@ impl Config { Ok(a) }), inner_statements: None, - }), + }, ) .add_var( - "eprint".to_string(), - Data::new(data::function::Function { + "eprint", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))), @@ -74,11 +74,11 @@ impl Config { Ok(Data::empty_tuple()) }), inner_statements: None, - }), + }, ) .add_var( - "eprintln".to_string(), - Data::new(data::function::Function { + "eprintln", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))), @@ -87,11 +87,11 @@ impl Config { Ok(Data::empty_tuple()) }), inner_statements: None, - }), + }, ) .add_var( - "print".to_string(), - Data::new(data::function::Function { + "print", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))), @@ -101,11 +101,11 @@ impl Config { Ok(Data::empty_tuple()) }), inner_statements: None, - }), + }, ) .add_var( - "println".to_string(), - Data::new(data::function::Function { + "println", + data::function::Function { info: program::run::Info::neverused(), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))), @@ -114,7 +114,7 @@ impl Config { Ok(Data::empty_tuple()) }), inner_statements: None, - }), + }, ) } } diff --git a/mers_lib/src/program/configs/with_string.rs b/mers_lib/src/program/configs/with_string.rs index 58fc648..2bd61e0 100755 --- a/mers_lib/src/program/configs/with_string.rs +++ b/mers_lib/src/program/configs/with_string.rs @@ -18,107 +18,98 @@ impl Config { /// `to_string: fn` turns any argument into a (more or less useful) string representation /// `concat: fn` concatenates all arguments given to it. arg must be an enumerable pub fn with_string(self) -> Self { - self.add_var( - "trim".to_string(), - Data::new(func(|v: &str, _| Ok(v.trim().to_owned()))), - ) - .add_var( - "index_of".to_string(), - Data::new(func(|(v, p): (&str, &str), _| { - Ok(OneOrNone(v.find(p).map(|v| v as isize))) - })), - ) - .add_var( - "index_of_rev".to_string(), - Data::new(func(|(v, p): (&str, &str), _| { - Ok(OneOrNone(v.rfind(p).map(|v| v as isize))) - })), - ) - .add_var( - "starts_with".to_string(), - Data::new(func(|(v, p): (&str, &str), _| Ok(v.starts_with(p)))), - ) - .add_var( - "ends_with".to_string(), - Data::new(func(|(v, p): (&str, &str), _| Ok(v.ends_with(p)))), - ) - .add_var( - "str_split_once".to_string(), - Data::new(func(|(v, p): (&str, &str), _| { - Ok(AnyOrNone( - v.split_once(p).map(|(a, b)| (a.to_owned(), b.to_owned())), - )) - })), - ) - .add_var( - "str_split_once_rev".to_string(), - Data::new(func(|(v, p): (&str, &str), _| { - Ok(AnyOrNone( - v.rsplit_once(p).map(|(a, b)| (a.to_owned(), b.to_owned())), - )) - })), - ) - .add_var( - "str_split".to_string(), - Data::new(func(|(v, p): (&str, &str), _| { - Ok(IterToList(v.split(p).map(|v| v.to_owned()))) - })), - ) - .add_var( - "concat".to_string(), - Data::new(util::to_mers_func( - |a| { - if a.iterable().is_some() { - Ok(Type::new(data::string::StringT)) - } else { - Err(format!("concat called on non-iterable type {a}").into()) - } - }, - |a| { - Ok(Data::new(data::string::String( - a.get() - .iterable() - .unwrap() - .map(|v| v.map(|v| v.get().to_string())) - .collect::>()?, - ))) - }, - )), - ) - .add_var( - "to_string".to_string(), - Data::new(util::to_mers_func( - |_a| Ok(Type::new(data::string::StringT)), - |a| Ok(Data::new(data::string::String(a.get().to_string()))), - )), - ) - .add_var( - "substring".to_string(), - Data::new(func(|v: OneOf<(&str, isize), (&str, isize, isize)>, _| { - let (s, start, end) = match v { - OneOf::A((t, s)) => (t, s, None), - OneOf::B((t, s, e)) => (t, s, Some(e)), - }; - let start = if start < 0 { - s.len().saturating_sub(start.abs() as usize) - } else { - start as usize - }; - let end = end - .map(|i| { - if i < 0 { - s.len().saturating_sub(i.abs() as usize) + self.add_var("trim", func(|v: &str, _| Ok(v.trim().to_owned()))) + .add_var( + "index_of", + func(|(v, p): (&str, &str), _| Ok(OneOrNone(v.find(p).map(|v| v as isize)))), + ) + .add_var( + "index_of_rev", + func(|(v, p): (&str, &str), _| Ok(OneOrNone(v.rfind(p).map(|v| v as isize)))), + ) + .add_var( + "starts_with", + func(|(v, p): (&str, &str), _| Ok(v.starts_with(p))), + ) + .add_var( + "ends_with", + func(|(v, p): (&str, &str), _| Ok(v.ends_with(p))), + ) + .add_var( + "str_split_once", + func(|(v, p): (&str, &str), _| { + Ok(AnyOrNone( + v.split_once(p).map(|(a, b)| (a.to_owned(), b.to_owned())), + )) + }), + ) + .add_var( + "str_split_once_rev", + func(|(v, p): (&str, &str), _| { + Ok(AnyOrNone( + v.rsplit_once(p).map(|(a, b)| (a.to_owned(), b.to_owned())), + )) + }), + ) + .add_var( + "str_split", + func(|(v, p): (&str, &str), _| Ok(IterToList(v.split(p).map(|v| v.to_owned())))), + ) + .add_var( + "concat", + util::to_mers_func( + |a| { + if a.iterable().is_some() { + Ok(Type::new(data::string::StringT)) } else { - i as usize + Err(format!("concat called on non-iterable type {a}").into()) } - }) - .unwrap_or(usize::MAX); - let end = end.min(s.len()); - if end < start { - return Ok(String::new()); - } - Ok(s[start..end].to_owned()) - })), - ) + }, + |a| { + Ok(Data::new(data::string::String( + a.get() + .iterable() + .unwrap() + .map(|v| v.map(|v| v.get().to_string())) + .collect::>()?, + ))) + }, + ), + ) + .add_var( + "to_string", + util::to_mers_func( + |_a| Ok(Type::new(data::string::StringT)), + |a| Ok(Data::new(data::string::String(a.get().to_string()))), + ), + ) + .add_var( + "substring", + func(|v: OneOf<(&str, isize), (&str, isize, isize)>, _| { + let (s, start, end) = match v { + OneOf::A((t, s)) => (t, s, None), + OneOf::B((t, s, e)) => (t, s, Some(e)), + }; + let start = if start < 0 { + s.len().saturating_sub(start.abs() as usize) + } else { + start as usize + }; + let end = end + .map(|i| { + if i < 0 { + s.len().saturating_sub(i.abs() as usize) + } else { + i as usize + } + }) + .unwrap_or(usize::MAX); + let end = end.min(s.len()); + if end < start { + return Ok(String::new()); + } + Ok(s[start..end].to_owned()) + }), + ) } }