diff --git a/src/packages/array_basic.rs b/src/packages/array_basic.rs index fc6ca5ec..d173bcf2 100644 --- a/src/packages/array_basic.rs +++ b/src/packages/array_basic.rs @@ -1,11 +1,12 @@ #![cfg(not(feature = "no_index"))] +#![allow(non_snake_case)] use crate::any::{Dynamic, Variant}; use crate::def_package; use crate::engine::{Array, Engine}; use crate::fn_native::FnPtr; -use crate::module::{FuncReturn, Module}; use crate::parser::{ImmutableString, INT}; +use crate::plugin::*; #[cfg(not(feature = "unchecked"))] use crate::{result::EvalAltResult, token::Position}; @@ -15,26 +16,148 @@ use crate::stdlib::{any::TypeId, boxed::Box}; #[cfg(not(feature = "unchecked"))] use crate::stdlib::string::ToString; -// Register array utility functions -fn push(list: &mut Array, item: T) -> FuncReturn<()> { - list.push(Dynamic::from(item)); - Ok(()) +pub type Unit = (); + +macro_rules! gen_array_functions { + ($root:ident => $($arg_type:ident),+ ) => { + pub mod $root { $( + pub mod $arg_type { + use super::super::*; + + #[export_fn] + pub fn push_func(list: &mut Array, item: $arg_type) { + super::super::push(list, item); + } + + #[export_fn] + pub fn insert_func(list: &mut Array, len: INT, item: $arg_type) { + super::super::insert(list, len, item); + } + } + )* } + } } -fn ins(list: &mut Array, position: INT, item: T) -> FuncReturn<()> { + +macro_rules! reg_functions { + ($mod_name:ident += $root:ident ; $($arg_type:ident),+) => { + $(set_exported_fn!($mod_name, "push", $root::$arg_type::push_func);)* + $(set_exported_fn!($mod_name, "insert", $root::$arg_type::insert_func);)* + } +} + +macro_rules! reg_pad { + ($lib:expr, $($par:ty),*) => { + $({ + $lib.set_raw_fn("pad", + &[TypeId::of::(), TypeId::of::(), TypeId::of::<$par>()], + pad::<$par> + ); + })* + }; +} + +def_package!(crate:BasicArrayPackage:"Basic array utilities.", lib, { + lib.merge(&exported_module!(array_functions)); + set_exported_fn!(lib, "+", append); + set_exported_fn!(lib, "+", concat); + + reg_functions!(lib += basic; INT, bool, char, ImmutableString, FnPtr, Array, Unit); + reg_pad!(lib, INT, bool, char, ImmutableString, FnPtr, Array, Unit); + + #[cfg(not(feature = "only_i32"))] + #[cfg(not(feature = "only_i64"))] + { + reg_functions!(lib += numbers; i8, u8, i16, u16, i32, i64, u32, u64); + reg_pad!(lib, u8, i16, u16, i32, u32, i64, u64); + + #[cfg(not(target_arch = "wasm32"))] + { + reg_functions!(lib += num_128; i128, u128); + reg_pad!(lib, i128, u128); + } + } + + #[cfg(not(feature = "no_float"))] + { + reg_functions!(lib += float; f32, f64); + reg_pad!(lib, f32, f64); + } + + #[cfg(not(feature = "no_object"))] + lib.set_getter_fn("len", |list: &mut Array| Ok(list.len() as INT)); + + // Register array iterator + lib.set_iter( + TypeId::of::(), + |arr| Box::new(arr.cast::().into_iter()) as Box>, + ); +}); + +#[export_fn] +fn append(x: &mut Array, y: Array) { + x.extend(y); +} +#[export_fn] +fn concat(mut x: Array, y: Array) -> Array { + x.extend(y); + x +} + +#[export_module] +mod array_functions { + pub fn len(list: &mut Array) -> INT { + list.len() as INT + } + pub fn append(x: &mut Array, y: Array) { + x.extend(y); + } + pub fn pop(list: &mut Array) -> Dynamic { + list.pop().unwrap_or_else(|| ().into()) + } + pub fn shift(list: &mut Array) -> Dynamic { + if list.is_empty() { + ().into() + } else { + list.remove(0) + } + } + pub fn remove(list: &mut Array, len: INT) -> Dynamic { + if len < 0 || (len as usize) >= list.len() { + ().into() + } else { + list.remove(len as usize) + } + } + pub fn clear(list: &mut Array) { + list.clear(); + } + pub fn truncate(list: &mut Array, len: INT) { + if len >= 0 { + list.truncate(len as usize); + } else { + list.clear(); + } + } +} + +// Register array utility functions +fn push(list: &mut Array, item: T) { + list.push(Dynamic::from(item)); +} +fn insert(list: &mut Array, position: INT, item: T) { if position <= 0 { list.insert(0, Dynamic::from(item)); } else if (position as usize) >= list.len() - 1 { - push(list, item)?; + push(list, item); } else { list.insert(position as usize, Dynamic::from(item)); } - Ok(()) } fn pad( _engine: &Engine, _: &Module, args: &mut [&mut Dynamic], -) -> FuncReturn<()> { +) -> Result<(), Box> { let len = *args[1].read_lock::().unwrap(); // Check if array will be over max size limit @@ -63,115 +186,16 @@ fn pad( Ok(()) } -macro_rules! reg_op { - ($lib:expr, $op:expr, $func:ident, $($par:ty),*) => { - $( $lib.set_fn_2_mut($op, $func::<$par>); )* - }; -} -macro_rules! reg_tri { - ($lib:expr, $op:expr, $func:ident, $($par:ty),*) => { - $( $lib.set_fn_3_mut($op, $func::<$par>); )* - }; -} -macro_rules! reg_pad { - ($lib:expr, $op:expr, $func:ident, $($par:ty),*) => { - $({ - $lib.set_raw_fn($op, - &[TypeId::of::(), TypeId::of::(), TypeId::of::<$par>()], - $func::<$par> - ); - })* - }; -} +gen_array_functions!(basic => INT, bool, char, ImmutableString, FnPtr, Array, Unit); -def_package!(crate:BasicArrayPackage:"Basic array utilities.", lib, { - reg_op!(lib, "push", push, INT, bool, char, ImmutableString, FnPtr, Array, ()); - reg_pad!(lib, "pad", pad, INT, bool, char, ImmutableString, FnPtr, Array, ()); - reg_tri!(lib, "insert", ins, INT, bool, char, ImmutableString, FnPtr, Array, ()); +#[cfg(not(feature = "only_i32"))] +#[cfg(not(feature = "only_i64"))] +gen_array_functions!(numbers => i8, u8, i16, u16, i32, i64, u32, u64); - lib.set_fn_2_mut("append", |x: &mut Array, y: Array| { - x.extend(y); - Ok(()) - }); - lib.set_fn_2_mut("+=", |x: &mut Array, y: Array| { - x.extend(y); - Ok(()) - }); - lib.set_fn_2( - "+", - |mut x: Array, y: Array| { - x.extend(y); - Ok(x) - }, - ); +#[cfg(not(feature = "only_i32"))] +#[cfg(not(feature = "only_i64"))] +#[cfg(not(target_arch = "wasm32"))] +gen_array_functions!(num_128 => i128, u128); - if cfg!(not(feature = "only_i32")) && cfg!(not(feature = "only_i64")) { - reg_op!(lib, "push", push, i8, u8, i16, u16, i32, i64, u32, u64); - reg_pad!(lib, "pad", pad, i8, u8, i16, u16, i32, u32, i64, u64); - reg_tri!(lib, "insert", ins, i8, u8, i16, u16, i32, i64, u32, u64); - - if cfg!(not(target_arch = "wasm32")) { - reg_op!(lib, "push", push, i128, u128); - reg_pad!(lib, "pad", pad, i128, u128); - reg_tri!(lib, "insert", ins, i128, u128); - } - } - - #[cfg(not(feature = "no_float"))] - { - reg_op!(lib, "push", push, f32, f64); - reg_pad!(lib, "pad", pad, f32, f64); - reg_tri!(lib, "insert", ins, f32, f64); - } - - lib.set_fn_1_mut( - "pop", - |list: &mut Array| Ok(list.pop().unwrap_or_else(|| ().into())), - ); - lib.set_fn_1_mut( - "shift", - |list: &mut Array| { - Ok(if list.is_empty() { - ().into() - } else { - list.remove(0) - }) - }, - ); - lib.set_fn_2_mut( - "remove", - |list: &mut Array, len: INT| { - Ok(if len < 0 || (len as usize) >= list.len() { - ().into() - } else { - list.remove(len as usize) - }) - }, - ); - lib.set_fn_1_mut("len", |list: &mut Array| Ok(list.len() as INT)); - - #[cfg(not(feature = "no_object"))] - lib.set_getter_fn("len", |list: &mut Array| Ok(list.len() as INT)); - - lib.set_fn_1_mut("clear", |list: &mut Array| { - list.clear(); - Ok(()) - }); - lib.set_fn_2_mut( - "truncate", - |list: &mut Array, len: INT| { - if len >= 0 { - list.truncate(len as usize); - } else { - list.clear(); - } - Ok(()) - }, - ); - - // Register array iterator - lib.set_iter( - TypeId::of::(), - |arr| Box::new(arr.cast::().into_iter()) as Box>, - ); -}); +#[cfg(not(feature = "no_float"))] +gen_array_functions!(float => f32, f64); diff --git a/src/packages/eval.rs b/src/packages/eval.rs index 6f97901d..6b2b9aa9 100644 --- a/src/packages/eval.rs +++ b/src/packages/eval.rs @@ -1,12 +1,14 @@ +use crate::any::Dynamic; use crate::def_package; -use crate::module::FuncReturn; use crate::parser::ImmutableString; +use crate::plugin::*; +use crate::result::EvalAltResult; + +#[export_fn(return_raw)] +fn eval_override(_script: ImmutableString) -> Result> { + Err("eval is evil!".into()) +} def_package!(crate:EvalPackage:"Disable 'eval'.", lib, { - lib.set_fn_1( - "eval", - |_: ImmutableString| -> FuncReturn<()> { - Err("eval is evil!".into()) - }, - ); + set_exported_fn!(lib, "eval", eval_override); }); diff --git a/src/packages/fn_basic.rs b/src/packages/fn_basic.rs index dde08fd5..8fe886dc 100644 --- a/src/packages/fn_basic.rs +++ b/src/packages/fn_basic.rs @@ -1,9 +1,16 @@ use crate::def_package; +use crate::engine::make_getter; use crate::fn_native::FnPtr; +use crate::plugin::*; + +#[export_fn] +fn get_fn_name(f: &mut FnPtr) -> ImmutableString { + f.get_fn_name().clone() +} def_package!(crate:BasicFnPackage:"Basic Fn functions.", lib, { - lib.set_fn_1_mut("name", |f: &mut FnPtr| Ok(f.get_fn_name().clone())); + set_exported_fn!(lib, "name", get_fn_name); #[cfg(not(feature = "no_object"))] - lib.set_getter_fn("name", |f: &mut FnPtr| Ok(f.get_fn_name().clone())); + set_exported_fn!(lib, make_getter("name"), get_fn_name); }); diff --git a/src/packages/logic.rs b/src/packages/logic.rs index 22f60d93..91ae1abf 100644 --- a/src/packages/logic.rs +++ b/src/packages/logic.rs @@ -2,7 +2,7 @@ use crate::def_package; use crate::plugin::*; macro_rules! gen_cmp_functions { - ($op_name:tt = $op_fn:ident ( $($arg_type:ident),+ ) -> $return_type:ident) => { + ($op_name:literal = $op_fn:ident ( $($arg_type:ident),+ ) -> $return_type:ident) => { pub mod $op_fn { $( pub mod $arg_type { use crate::plugin::*; diff --git a/src/packages/time_basic.rs b/src/packages/time_basic.rs index 61843b14..8a216b2d 100644 --- a/src/packages/time_basic.rs +++ b/src/packages/time_basic.rs @@ -1,5 +1,4 @@ #![cfg(not(feature = "no_std"))] -use super::logic::{eq, gt, gte, lt, lte, ne}; #[cfg(feature = "no_float")] #[cfg(not(feature = "unchecked"))] @@ -38,12 +37,12 @@ def_package!(crate:BasicTimePackage:"Basic timing utilities.", lib, { //lib.merge(&exported_module!(time_compare)); - lib.set_fn_2("<", |x:Instant, y:Instant| Ok(lt(x, y))); - lib.set_fn_2("<=", |x:Instant, y:Instant| Ok(lte(x, y))); - lib.set_fn_2(">", |x:Instant, y:Instant| Ok(gt(x, y))); - lib.set_fn_2(">=", |x:Instant, y:Instant| Ok(gte(x, y))); - lib.set_fn_2("==", |x:Instant, y:Instant| Ok(eq(x, y))); - lib.set_fn_2("!=", |x:Instant, y:Instant| Ok(ne(x, y))); + lib.set_fn_2("<", |x:Instant, y:Instant| Ok(x < y)); + lib.set_fn_2("<=", |x:Instant, y:Instant| Ok(x <= y)); + lib.set_fn_2(">", |x:Instant, y:Instant| Ok(x > y)); + lib.set_fn_2(">=", |x:Instant, y:Instant| Ok(x >= y)); + lib.set_fn_2("==", |x:Instant, y:Instant| Ok(x == y)); + lib.set_fn_2("!=", |x:Instant, y:Instant| Ok(x != y)); }); #[export_fn]