Implement print/debug functions via Dynamic parameters.

This commit is contained in:
Stephen Chung
2021-02-23 19:08:05 +08:00
parent ba2b0630f7
commit 36420f0b99
4 changed files with 173 additions and 142 deletions

View File

@@ -1,13 +1,8 @@
#![allow(non_snake_case)]
use crate::engine::{KEYWORD_DEBUG, KEYWORD_PRINT};
use crate::plugin::*;
use crate::stdlib::{
fmt::{Debug, Display},
format,
string::ToString,
};
use crate::{def_package, FnPtr, ImmutableString, INT};
use crate::stdlib::{format, string::ToString};
use crate::{def_package, FnPtr, ImmutableString};
#[cfg(not(feature = "no_index"))]
use crate::Array;
@@ -15,139 +10,12 @@ use crate::Array;
#[cfg(not(feature = "no_object"))]
use crate::Map;
#[cfg(feature = "decimal")]
use rust_decimal::Decimal;
const FUNC_TO_STRING: &'static str = "to_string";
const FUNC_TO_DEBUG: &'static str = "to_debug";
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(pure)]
pub fn to_string_func(x: &mut $arg_type) -> ImmutableString {
super::super::$fn_name(x)
}
})* }
}
}
macro_rules! reg_print_functions {
($mod_name:ident += $root:ident ; $($arg_type:ident),+) => { $(
set_exported_fn!($mod_name, FUNC_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, FUNC_TO_DEBUG, $root::$arg_type::to_string_func);
set_exported_fn!($mod_name, KEYWORD_DEBUG, $root::$arg_type::to_string_func);
)* }
}
def_package!(crate:BasicStringPackage:"Basic string utilities, including printing.", lib, {
combine_with_exported_module!(lib, "print_debug", print_debug_functions);
reg_print_functions!(lib += print_basic; INT, bool, char, FnPtr);
reg_debug_functions!(lib += debug_basic; INT, bool, Unit, char, ImmutableString);
#[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);
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
{
reg_print_functions!(lib += print_num_128; i128, u128);
reg_debug_functions!(lib += debug_num_128; i128, u128);
}
}
#[cfg(not(feature = "no_float"))]
{
reg_print_functions!(lib += print_float_64; f64);
reg_debug_functions!(lib += print_float_64; f64);
reg_print_functions!(lib += print_float_32; f32);
reg_debug_functions!(lib += print_float_32; f32);
}
#[cfg(feature = "decimal")]
{
reg_print_functions!(lib += print_decimal; Decimal);
reg_debug_functions!(lib += debug_decimal; Decimal);
}
});
fn to_string<T: Display>(x: &mut T) -> ImmutableString {
x.to_string().into()
}
fn to_debug<T: Debug>(x: &mut T) -> ImmutableString {
format!("{:?}", x).into()
}
#[cfg(not(feature = "no_float"))]
fn print_f64(x: &mut f64) -> ImmutableString {
#[cfg(feature = "no_std")]
use num_traits::Float;
let abs = x.abs();
if abs > 10000000000000.0 || abs < 0.0000000000001 {
format!("{:e}", x).into()
} else {
x.to_string().into()
}
}
#[cfg(not(feature = "no_float"))]
fn print_f32(x: &mut f32) -> ImmutableString {
#[cfg(feature = "no_std")]
use num_traits::Float;
let abs = x.abs();
if abs > 10000000000000.0 || abs < 0.0000000000001 {
format!("{:e}", x).into()
} else {
x.to_string().into()
}
}
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(any(target_arch = "wasm32", target_arch = "wasm64")))]
gen_functions!(print_num_128 => to_string(i128, u128));
#[cfg(not(feature = "only_i32"))]
#[cfg(not(feature = "only_i64"))]
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
gen_functions!(debug_num_128 => to_debug(i128, u128));
#[cfg(not(feature = "no_float"))]
gen_functions!(print_float_64 => print_f64(f64));
#[cfg(not(feature = "no_float"))]
gen_functions!(print_float_32 => print_f32(f32));
#[cfg(feature = "decimal")]
gen_functions!(print_decimal => to_string(Decimal));
#[cfg(feature = "decimal")]
gen_functions!(debug_decimal => to_debug(Decimal));
// Register print and debug
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
@@ -162,6 +30,16 @@ fn print_with_func(fn_name: &str, ctx: &NativeCallContext, value: &mut Dynamic)
#[export_module]
mod print_debug_functions {
use crate::ImmutableString;
#[rhai_fn(name = "print", name = "to_string", pure)]
pub fn print_generic(item: &mut Dynamic) -> ImmutableString {
item.to_string().into()
}
#[rhai_fn(name = "debug", name = "to_debug", pure)]
pub fn debug_generic(item: &mut Dynamic) -> ImmutableString {
format!("{:?}", item).into()
}
#[rhai_fn(name = "print", name = "debug")]
pub fn print_empty_string() -> ImmutableString {
"".to_string().into()
@@ -176,7 +54,43 @@ mod print_debug_functions {
}
#[rhai_fn(name = "debug", pure)]
pub fn debug_fn_ptr(f: &mut FnPtr) -> ImmutableString {
to_string(f)
f.to_string().into()
}
#[cfg(not(feature = "no_float"))]
pub mod float_functions {
#[rhai_fn(name = "print", name = "to_string")]
pub fn print_f64(number: f64) -> ImmutableString {
#[cfg(feature = "no_std")]
use num_traits::Float;
let abs = number.abs();
if abs > 10000000000000.0 || abs < 0.0000000000001 {
format!("{:e}", number).into()
} else {
number.to_string().into()
}
}
#[rhai_fn(name = "print", name = "to_string")]
pub fn print_f32(number: f32) -> ImmutableString {
#[cfg(feature = "no_std")]
use num_traits::Float;
let abs = number.abs();
if abs > 10000000000000.0 || abs < 0.0000000000001 {
format!("{:e}", number).into()
} else {
number.to_string().into()
}
}
#[rhai_fn(name = "debug", name = "to_debug")]
pub fn debug_f64(number: f64) -> ImmutableString {
number.to_string().into()
}
#[rhai_fn(name = "debug", name = "to_debug")]
pub fn debug_f32(number: f32) -> ImmutableString {
number.to_string().into()
}
}
#[cfg(not(feature = "no_index"))]