diff --git a/src/packages/array_basic.rs b/src/packages/array_basic.rs index c044eddc..fc44c4c5 100644 --- a/src/packages/array_basic.rs +++ b/src/packages/array_basic.rs @@ -3,8 +3,6 @@ use crate::any::{Dynamic, Variant}; use crate::def_package; -#[cfg(not(feature = "no_object"))] -use crate::engine::make_getter; use crate::engine::{Array, Engine}; use crate::fn_native::FnPtr; use crate::parser::{ImmutableString, INT}; @@ -13,6 +11,9 @@ use crate::plugin::*; #[cfg(not(feature = "unchecked"))] use crate::{result::EvalAltResult, token::Position}; +#[cfg(not(feature = "no_object"))] +use crate::engine::make_getter; + use crate::stdlib::{any::TypeId, boxed::Box}; #[cfg(not(feature = "unchecked"))] diff --git a/src/packages/fn_basic.rs b/src/packages/fn_basic.rs index fd3b5052..e34cb918 100644 --- a/src/packages/fn_basic.rs +++ b/src/packages/fn_basic.rs @@ -1,9 +1,10 @@ use crate::def_package; -#[cfg(not(feature = "no_object"))] -use crate::engine::make_getter; use crate::fn_native::FnPtr; use crate::plugin::*; +#[cfg(not(feature = "no_object"))] +use crate::engine::make_getter; + #[export_fn] fn get_fn_name(f: &mut FnPtr) -> ImmutableString { f.get_fn_name().clone() diff --git a/src/packages/math_basic.rs b/src/packages/math_basic.rs index f8b905b2..aad542b1 100644 --- a/src/packages/math_basic.rs +++ b/src/packages/math_basic.rs @@ -1,6 +1,4 @@ use crate::def_package; -#[cfg(not(feature = "no_object"))] -use crate::engine::make_getter; use crate::parser::INT; use crate::plugin::*; @@ -10,6 +8,9 @@ use crate::parser::FLOAT; #[cfg(not(feature = "no_float"))] use crate::{result::EvalAltResult, token::Position}; +#[cfg(not(feature = "no_object"))] +use crate::engine::make_getter; + #[cfg(feature = "no_std")] #[cfg(not(feature = "no_float"))] use num_traits::float::Float; diff --git a/src/packages/string_basic.rs b/src/packages/string_basic.rs index 08778150..712faed1 100644 --- a/src/packages/string_basic.rs +++ b/src/packages/string_basic.rs @@ -1,8 +1,10 @@ +#![allow(non_snake_case)] + use crate::def_package; use crate::engine::{FN_TO_STRING, KEYWORD_DEBUG, KEYWORD_PRINT}; use crate::fn_native::FnPtr; -use crate::module::FuncReturn; use crate::parser::{ImmutableString, INT}; +use crate::plugin::*; #[cfg(not(feature = "no_index"))] use crate::engine::Array; @@ -16,76 +18,136 @@ use crate::stdlib::{ string::ToString, }; -// Register print and debug -fn to_debug(x: &mut T) -> FuncReturn { - Ok(format!("{:?}", x).into()) -} -fn to_string(x: &mut T) -> FuncReturn { - Ok(x.to_string().into()) -} -#[cfg(not(feature = "no_object"))] -fn format_map(x: &mut Map) -> FuncReturn { - Ok(format!("#{:?}", x).into()) +type Unit = (); + +macro_rules! gen_functions { + ($root:ident => $fn_name:ident ( $($arg_type:ident),+ )) => { + pub mod $root { $( + pub mod $arg_type { + use super::super::*; + + #[export_fn] + pub fn to_string_func(x: &mut $arg_type) -> ImmutableString { + super::super::$fn_name(x) + } + } + )* } + } } -macro_rules! reg_op { - ($lib:expr, $op:expr, $func:ident, $($par:ty),*) => { - $( $lib.set_fn_1_mut($op, $func::<$par>); )* - }; +macro_rules! reg_print_functions { + ($mod_name:ident += $root:ident ; $($arg_type:ident),+) => { + $(set_exported_fn!($mod_name, FN_TO_STRING, $root::$arg_type::to_string_func);)* + $(set_exported_fn!($mod_name, KEYWORD_PRINT, $root::$arg_type::to_string_func);)* + } +} + +macro_rules! reg_debug_functions { + ($mod_name:ident += $root:ident ; $($arg_type:ident),+) => { + $(set_exported_fn!($mod_name, KEYWORD_DEBUG, $root::$arg_type::to_string_func);)* + } } def_package!(crate:BasicStringPackage:"Basic string utilities, including printing.", lib, { - reg_op!(lib, KEYWORD_PRINT, to_string, INT, bool, char, FnPtr); - reg_op!(lib, FN_TO_STRING, to_string, INT, bool, char, FnPtr); - lib.set_fn_1_mut(KEYWORD_DEBUG, |f: &mut FnPtr| Ok(f.to_string())); + reg_print_functions!(lib += print_basic; INT, bool, char, FnPtr); + set_exported_fn!(lib, KEYWORD_PRINT, print_empty_string); + set_exported_fn!(lib, KEYWORD_PRINT, print_unit); + set_exported_fn!(lib, FN_TO_STRING, print_unit); + set_exported_fn!(lib, KEYWORD_PRINT, print_string); + set_exported_fn!(lib, FN_TO_STRING, print_string); - lib.set_fn_0(KEYWORD_PRINT, || Ok("".to_string())); - lib.set_fn_1(KEYWORD_PRINT, |_: ()| Ok("".to_string())); - lib.set_fn_1(FN_TO_STRING, |_: ()| Ok("".to_string())); + reg_debug_functions!(lib += debug_basic; INT, bool, Unit, char, ImmutableString); + set_exported_fn!(lib, KEYWORD_DEBUG, print_empty_string); + set_exported_fn!(lib, KEYWORD_DEBUG, debug_fn_ptr); - lib.set_fn_1(KEYWORD_PRINT, |s: ImmutableString| Ok(s)); - lib.set_fn_1(FN_TO_STRING, |s: ImmutableString| Ok(s)); + #[cfg(not(feature = "only_i32"))] + #[cfg(not(feature = "only_i64"))] + { + reg_print_functions!(lib += print_numbers; i8, u8, i16, u16, i32, u32, i64, u64); + reg_debug_functions!(lib += debug_numbers; i8, u8, i16, u16, i32, u32, i64, u64); - reg_op!(lib, KEYWORD_DEBUG, to_debug, INT, bool, (), char, ImmutableString); - - if cfg!(not(feature = "only_i32")) && cfg!(not(feature = "only_i64")) { - reg_op!(lib, KEYWORD_PRINT, to_string, i8, u8, i16, u16, i32, u32); - reg_op!(lib, FN_TO_STRING, to_string, i8, u8, i16, u16, i32, u32); - reg_op!(lib, KEYWORD_DEBUG, to_debug, i8, u8, i16, u16, i32, u32); - reg_op!(lib, KEYWORD_PRINT, to_string, i64, u64); - reg_op!(lib, FN_TO_STRING, to_string, i64, u64); - reg_op!(lib, KEYWORD_DEBUG, to_debug, i64, u64); - - if cfg!(not(target_arch = "wasm32")) { - reg_op!(lib, KEYWORD_PRINT, to_string, i128, u128); - reg_op!(lib, FN_TO_STRING, to_string, i128, u128); - reg_op!(lib, KEYWORD_DEBUG, to_debug, i128, u128); + #[cfg(not(target_arch = "wasm32"))] + { + reg_print_functions!(lib += print_num_128; i128, u128); + reg_debug_functions!(lib += debug_num_128; i128, u128); } } #[cfg(not(feature = "no_float"))] { - reg_op!(lib, KEYWORD_PRINT, to_string, f32, f64); - reg_op!(lib, FN_TO_STRING, to_string, f32, f64); - reg_op!(lib, KEYWORD_DEBUG, to_debug, f32, f64); + reg_print_functions!(lib += print_float; f32, f64); + reg_debug_functions!(lib += debug_float; f32, f64); } #[cfg(not(feature = "no_index"))] { - reg_op!(lib, KEYWORD_PRINT, to_debug, Array); - reg_op!(lib, FN_TO_STRING, to_debug, Array); - reg_op!(lib, KEYWORD_DEBUG, to_debug, Array); + reg_print_functions!(lib += print_array; Array); + reg_debug_functions!(lib += print_array; Array); } #[cfg(not(feature = "no_object"))] { - lib.set_fn_1_mut(KEYWORD_PRINT, format_map); - lib.set_fn_1_mut(FN_TO_STRING, format_map); - lib.set_fn_1_mut(KEYWORD_DEBUG, format_map); + set_exported_fn!(lib, KEYWORD_PRINT, format_map); + set_exported_fn!(lib, FN_TO_STRING, format_map); + set_exported_fn!(lib, KEYWORD_DEBUG, format_map); } - - lib.set_fn_2("+", |s: ImmutableString, ch: char| Ok(s + ch)); - lib.set_fn_2_mut("+=", |s: &mut ImmutableString, ch: char| { *s += ch; Ok(()) }); - lib.set_fn_2_mut("append", |s: &mut ImmutableString, ch: char| { *s += ch; Ok(()) }); - lib.set_fn_2_mut("append", |s: &mut ImmutableString, s2: ImmutableString| { *s += &s2; Ok(()) }); }); + +gen_functions!(print_basic => to_string(INT, bool, char, FnPtr)); +gen_functions!(debug_basic => to_debug(INT, bool, Unit, char, ImmutableString)); + +#[cfg(not(feature = "only_i32"))] +#[cfg(not(feature = "only_i64"))] +gen_functions!(print_numbers => to_string(i8, u8, i16, u16, i32, u32, i64, u64)); + +#[cfg(not(feature = "only_i32"))] +#[cfg(not(feature = "only_i64"))] +gen_functions!(debug_numbers => to_debug(i8, u8, i16, u16, i32, u32, i64, u64)); + +#[cfg(not(feature = "only_i32"))] +#[cfg(not(feature = "only_i64"))] +#[cfg(not(target_arch = "wasm32"))] +gen_functions!(print_num_128 => to_string(i128, u128)); + +#[cfg(not(feature = "only_i32"))] +#[cfg(not(feature = "only_i64"))] +#[cfg(not(target_arch = "wasm32"))] +gen_functions!(debug_num_128 => to_debug(i128, u128)); + +#[cfg(not(feature = "no_float"))] +gen_functions!(print_float => to_string(f32, f64)); + +#[cfg(not(feature = "no_float"))] +gen_functions!(debug_float => to_debug(f32, f64)); + +#[cfg(not(feature = "no_index"))] +gen_functions!(print_array => to_debug(Array)); + +// Register print and debug +#[export_fn] +fn print_empty_string() -> ImmutableString { + "".to_string().into() +} +#[export_fn] +fn print_unit(_x: ()) -> ImmutableString { + "".to_string().into() +} +#[export_fn] +fn print_string(s: ImmutableString) -> ImmutableString { + s +} +#[export_fn] +fn debug_fn_ptr(f: &mut FnPtr) -> ImmutableString { + f.to_string().into() +} +fn to_string(x: &mut T) -> ImmutableString { + x.to_string().into() +} +fn to_debug(x: &mut T) -> ImmutableString { + format!("{:?}", x).into() +} +#[cfg(not(feature = "no_object"))] +#[export_fn] +fn format_map(x: &mut Map) -> ImmutableString { + format!("#{:?}", x).into() +} diff --git a/src/packages/string_more.rs b/src/packages/string_more.rs index d3b913fa..ded48378 100644 --- a/src/packages/string_more.rs +++ b/src/packages/string_more.rs @@ -2,8 +2,6 @@ use crate::any::Dynamic; use crate::def_package; -#[cfg(not(feature = "no_object"))] -use crate::engine::make_getter; use crate::engine::Engine; use crate::fn_native::FnPtr; use crate::parser::{ImmutableString, INT}; @@ -13,6 +11,9 @@ use crate::utils::StaticVec; #[cfg(not(feature = "unchecked"))] use crate::{result::EvalAltResult, token::Position}; +#[cfg(not(feature = "no_object"))] +use crate::engine::make_getter; + use crate::stdlib::{ any::TypeId, boxed::Box, fmt::Display, format, mem, string::String, string::ToString, vec::Vec, }; @@ -73,6 +74,7 @@ def_package!(crate:MoreStringPackage:"Additional string utilities, including str set_exported_fn!(lib, "index_of", string_funcs::index_of_string); set_exported_fn!(lib, "index_of", string_funcs::index_of_string_starting_from); set_exported_fn!(lib, "append", string_funcs::append_char); + set_exported_fn!(lib, "+=", string_funcs::append_char); set_exported_fn!(lib, "append", string_funcs::append_string); set_exported_fn!(lib, "sub_string", string_funcs::sub_string); set_exported_fn!(lib, "sub_string", string_funcs::sub_string_starting_from); @@ -193,8 +195,8 @@ mod string_functions { mod string_funcs_array { use crate::engine::Array; use crate::plugin::*; - use crate::utils::ImmutableString; use crate::stdlib::string::String; + use crate::utils::ImmutableString; #[export_fn] pub fn append_array(x: &mut ImmutableString, y: Array) -> String { @@ -209,8 +211,8 @@ mod string_funcs_array { mod string_funcs { use crate::parser::INT; use crate::plugin::*; - use crate::utils::{ImmutableString, StaticVec}; use crate::stdlib::string::{String, ToString}; + use crate::utils::{ImmutableString, StaticVec}; #[export_fn] pub fn append_unit(s: ImmutableString, _x: ()) -> ImmutableString { @@ -280,11 +282,11 @@ mod string_funcs { } #[export_fn] pub fn append_char(s: &mut ImmutableString, ch: char) { - s.make_mut().push(ch); + *s += ch; } #[export_fn] pub fn append_string(s: &mut ImmutableString, add: ImmutableString) { - s.make_mut().push_str(add.as_str()); + *s += &add; } #[export_fn] pub fn sub_string(s: ImmutableString, start: INT, len: INT) -> ImmutableString { diff --git a/src/packages/time_basic.rs b/src/packages/time_basic.rs index 0b3cad13..55315cee 100644 --- a/src/packages/time_basic.rs +++ b/src/packages/time_basic.rs @@ -5,8 +5,6 @@ use super::math_basic::MAX_INT; use crate::def_package; -#[cfg(not(feature = "no_object"))] -use crate::engine::make_getter; use crate::plugin::*; use crate::result::EvalAltResult; @@ -20,6 +18,9 @@ use crate::parser::INT; #[cfg(not(feature = "unchecked"))] use crate::token::Position; +#[cfg(not(feature = "no_object"))] +use crate::engine::make_getter; + #[cfg(not(target_arch = "wasm32"))] use crate::stdlib::time::Instant;