From a24d11324c405e26a4d49301d2567a797dfcd01d Mon Sep 17 00:00:00 2001 From: J Henry Waugh Date: Sun, 9 Aug 2020 11:21:26 -0500 Subject: [PATCH 1/5] Create functional test for generated bulk operations --- tests/macro_unroll.rs | 48 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 tests/macro_unroll.rs diff --git a/tests/macro_unroll.rs b/tests/macro_unroll.rs new file mode 100644 index 00000000..17f2dfb9 --- /dev/null +++ b/tests/macro_unroll.rs @@ -0,0 +1,48 @@ +#![cfg(not(any(feature = "no_index", feature = "no_module")))] + +use rhai::plugin::*; +use rhai::{Engine, EvalAltResult, INT, Module}; + +macro_rules! generate_add { + ($type_name:ident) => { + pub mod $type_name { + use rhai::plugin::*; + #[export_fn] + pub fn add(x: $type_name, y: $type_name) -> $type_name { + x + y + } + } + } +} + +macro_rules! register_adds_in_bulk { + ($mod_name:expr, $($type_names:ident),+) => { + $( + { + let type_str = stringify!($type_names); + register_exported_fn!($mod_name, + format!("add_{}", type_str), + crate::$type_names::add); + } + )* + } +} + +generate_add!(i8); +generate_add!(i16); +generate_add!(i32); +generate_add!(i64); + +#[test] +fn test_generated_adds() -> Result<(), Box> { + let mut engine = Engine::new(); + + let mut m = Module::new(); + register_adds_in_bulk!(m, i8, i16, i32, i64); + + engine.load_package(m); + + assert_eq!(engine.eval::("let a = 0; add_i64(a, 1)")?, 1); + + Ok(()) +} From dc7b36fd11ebf2ca8ee9b18ff5e0628777993740 Mon Sep 17 00:00:00 2001 From: J Henry Waugh Date: Sun, 9 Aug 2020 11:42:37 -0500 Subject: [PATCH 2/5] Fix for stable --- tests/macro_unroll.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/macro_unroll.rs b/tests/macro_unroll.rs index 17f2dfb9..9b4a7b75 100644 --- a/tests/macro_unroll.rs +++ b/tests/macro_unroll.rs @@ -16,7 +16,7 @@ macro_rules! generate_add { } macro_rules! register_adds_in_bulk { - ($mod_name:expr, $($type_names:ident),+) => { + ($mod_name:ident, $($type_names:ident),+) => { $( { let type_str = stringify!($type_names); From a45b1d406f89fa285c1eb52f9ec032c39da928ad Mon Sep 17 00:00:00 2001 From: J Henry Waugh Date: Sun, 9 Aug 2020 11:47:11 -0500 Subject: [PATCH 3/5] Add only_i32 feature support --- tests/macro_unroll.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/macro_unroll.rs b/tests/macro_unroll.rs index 9b4a7b75..c253666f 100644 --- a/tests/macro_unroll.rs +++ b/tests/macro_unroll.rs @@ -42,6 +42,9 @@ fn test_generated_adds() -> Result<(), Box> { engine.load_package(m); + #[cfg(feature = "only_i32")] + assert_eq!(engine.eval::("let a = 0; add_i32(a, 1)")?, 1); + #[cfg(not(feature = "only_i32"))] assert_eq!(engine.eval::("let a = 0; add_i64(a, 1)")?, 1); Ok(()) From 3fa252e73254741c24a1d5ded280585faad78d17 Mon Sep 17 00:00:00 2001 From: J Henry Waugh Date: Sun, 9 Aug 2020 11:57:09 -0500 Subject: [PATCH 4/5] Fold generate_add once more --- tests/macro_unroll.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/tests/macro_unroll.rs b/tests/macro_unroll.rs index c253666f..f24e2d3b 100644 --- a/tests/macro_unroll.rs +++ b/tests/macro_unroll.rs @@ -3,15 +3,17 @@ use rhai::plugin::*; use rhai::{Engine, EvalAltResult, INT, Module}; -macro_rules! generate_add { - ($type_name:ident) => { - pub mod $type_name { +macro_rules! generate_adds { + ($($type_names:ident),+) => { + $( + pub mod $type_names { use rhai::plugin::*; #[export_fn] - pub fn add(x: $type_name, y: $type_name) -> $type_name { + pub fn add(x: $type_names, y: $type_names) -> $type_names { x + y } } + )* } } @@ -28,10 +30,7 @@ macro_rules! register_adds_in_bulk { } } -generate_add!(i8); -generate_add!(i16); -generate_add!(i32); -generate_add!(i64); +generate_adds!(i8, i16, i32, i64); #[test] fn test_generated_adds() -> Result<(), Box> { From ce8fbe40c4edccc705cca9edbffff1d8599e98fb Mon Sep 17 00:00:00 2001 From: J Henry Waugh Date: Sun, 9 Aug 2020 12:13:02 -0500 Subject: [PATCH 5/5] Fold into fully generic form --- tests/macro_unroll.rs | 52 +++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/tests/macro_unroll.rs b/tests/macro_unroll.rs index f24e2d3b..fd0920ed 100644 --- a/tests/macro_unroll.rs +++ b/tests/macro_unroll.rs @@ -3,41 +3,54 @@ use rhai::plugin::*; use rhai::{Engine, EvalAltResult, INT, Module}; -macro_rules! generate_adds { - ($($type_names:ident),+) => { - $( - pub mod $type_names { - use rhai::plugin::*; - #[export_fn] - pub fn add(x: $type_names, y: $type_names) -> $type_names { - x + y - } +pub fn add_generic>(x: T, y: T) -> T { + x + y +} + +pub fn mul_generic>(x: T, y: T) -> T { + 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 { - ($mod_name:ident, $($type_names:ident),+) => { +macro_rules! register_in_bulk { + ($mod_name:ident, $op_name:ident, $($type_names:ident),+) => { $( { let type_str = stringify!($type_names); register_exported_fn!($mod_name, - format!("add_{}", type_str), - crate::$type_names::add); + format!(concat!(stringify!($op_name), "_{}"), type_str), + 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] -fn test_generated_adds() -> Result<(), Box> { +fn test_generated_ops() -> Result<(), Box> { let mut engine = Engine::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); @@ -46,5 +59,10 @@ fn test_generated_adds() -> Result<(), Box> { #[cfg(not(feature = "only_i32"))] assert_eq!(engine.eval::("let a = 0; add_i64(a, 1)")?, 1); + #[cfg(feature = "only_i32")] + assert_eq!(engine.eval::("let a = 1; mul_i32(a, 2)")?, 2); + #[cfg(not(feature = "only_i32"))] + assert_eq!(engine.eval::("let a = 1; mul_i64(a, 2)")?, 2); + Ok(()) }