Fold into fully generic form

This commit is contained in:
J Henry Waugh 2020-08-09 12:13:02 -05:00
parent 3fa252e732
commit ce8fbe40c4

View File

@ -3,41 +3,54 @@
use rhai::plugin::*; use rhai::plugin::*;
use rhai::{Engine, EvalAltResult, INT, Module}; use rhai::{Engine, EvalAltResult, INT, Module};
macro_rules! generate_adds { pub fn add_generic<T: std::ops::Add<Output = T>>(x: T, y: T) -> T {
($($type_names:ident),+) => { x + y
$( }
pub mod $type_names {
use rhai::plugin::*; pub fn mul_generic<T: std::ops::Mul<Output = T>>(x: T, y: T) -> T {
#[export_fn] x * y
pub fn add(x: $type_names, y: $type_names) -> $type_names { }
x + y
} macro_rules! generate_ops {
($op_name:ident, $op_fn:ident, $($type_names:ident),+) => {
pub mod $op_name {
$(
pub mod $type_names {
use rhai::plugin::*;
use super::super::$op_fn;
#[export_fn]
pub fn op(x: $type_names, y: $type_names) -> $type_names {
$op_fn(x, y)
}
}
)*
} }
)*
} }
} }
macro_rules! register_adds_in_bulk { macro_rules! register_in_bulk {
($mod_name:ident, $($type_names:ident),+) => { ($mod_name:ident, $op_name:ident, $($type_names:ident),+) => {
$( $(
{ {
let type_str = stringify!($type_names); let type_str = stringify!($type_names);
register_exported_fn!($mod_name, register_exported_fn!($mod_name,
format!("add_{}", type_str), format!(concat!(stringify!($op_name), "_{}"), type_str),
crate::$type_names::add); crate::$op_name::$type_names::op);
} }
)* )*
} }
} }
generate_adds!(i8, i16, i32, i64); generate_ops!(add, add_generic, i8, i16, i32, i64);
generate_ops!(mul, mul_generic, i8, i16, i32, i64);
#[test] #[test]
fn test_generated_adds() -> Result<(), Box<EvalAltResult>> { fn test_generated_ops() -> Result<(), Box<EvalAltResult>> {
let mut engine = Engine::new(); let mut engine = Engine::new();
let mut m = Module::new(); let mut m = Module::new();
register_adds_in_bulk!(m, i8, i16, i32, i64); register_in_bulk!(m, add, i8, i16, i32, i64);
register_in_bulk!(m, mul, i8, i16, i32, i64);
engine.load_package(m); engine.load_package(m);
@ -46,5 +59,10 @@ fn test_generated_adds() -> Result<(), Box<EvalAltResult>> {
#[cfg(not(feature = "only_i32"))] #[cfg(not(feature = "only_i32"))]
assert_eq!(engine.eval::<INT>("let a = 0; add_i64(a, 1)")?, 1); assert_eq!(engine.eval::<INT>("let a = 0; add_i64(a, 1)")?, 1);
#[cfg(feature = "only_i32")]
assert_eq!(engine.eval::<INT>("let a = 1; mul_i32(a, 2)")?, 2);
#[cfg(not(feature = "only_i32"))]
assert_eq!(engine.eval::<INT>("let a = 1; mul_i64(a, 2)")?, 2);
Ok(()) Ok(())
} }