From bcb9d130c757e474f7050472f2be3d3287b5c498 Mon Sep 17 00:00:00 2001 From: Rowan Torbitzky-Lane Date: Fri, 18 Apr 2025 14:06:21 -0500 Subject: [PATCH] conversion to new instructions started --- rush_macro/src/lib.rs | 3 + rush_macro/src/utils/instruction.rs | 33 ++- src/instructions/logical.rs | 76 +++--- src/instructions/mod.rs | 14 +- src/instructions/numeric.rs | 391 ++++++++++++---------------- 5 files changed, 241 insertions(+), 276 deletions(-) diff --git a/rush_macro/src/lib.rs b/rush_macro/src/lib.rs index 8bf6864..dffb7c6 100644 --- a/rush_macro/src/lib.rs +++ b/rush_macro/src/lib.rs @@ -34,6 +34,9 @@ mod utils; /// ``` /// would have the ; placed at the end of the instruction. Check rush's `tests/instruction_test.rs` /// file for an example using this code. +/// +/// Suggestion: If you need to pull an index from the int stack, make it the first argument +/// to your function. #[proc_macro] pub fn run_instruction(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let f = parse_macro_input!(input as Extract); diff --git a/rush_macro/src/utils/instruction.rs b/rush_macro/src/utils/instruction.rs index e7ea2e0..4ce912f 100644 --- a/rush_macro/src/utils/instruction.rs +++ b/rush_macro/src/utils/instruction.rs @@ -64,31 +64,56 @@ impl ToTokens for Extract { } } + // Ensure stacks have enough values let conditions = counts.iter().map(|(stack, count)| { let inner_stack = &stack.0; quote! { #inner_state.#inner_stack.len() >= #count } }); - let values = stacks.iter().map(|stack| { + // Create variables to store popped values + let store_values = stacks.iter().enumerate().map(|(i, stack)| { let inner_stack = &&stack.0; - quote! { #inner_state.#inner_stack.pop().unwrap() } + let var_name = quote::format_ident!("val_{}", i); + quote! { let #var_name = #inner_state.#inner_stack.pop().unwrap(); } }); + // Create slices of variable names for restoration + let value_vars = (0..stacks.len()) + .map(|i| quote::format_ident!("val_{}", i)) + .collect::>(); + + // Create restore operations for each stack + let restore_values = stacks + .iter() + .zip(value_vars.iter().rev()) + .map(|(stack, var)| { + let inner_stack = &&stack.0; + quote! { #inner_state.#inner_stack.push(#var); } + }); + + // Run the function using auxiliary mode if needed let aux_run = match aux { true => quote! { - if let Some(result) = #inner_func(#(#values),*) { + let result = #inner_func(#(#value_vars),*); + if let Some(result) = result { #inner_state.#inner_out_stack.extend(result.iter()); + } else { + #(#restore_values)* } }, false => quote! { - if let Some(result) = #inner_func(#(#values),*) { + let result = #inner_func(#(#value_vars),*); + if let Some(result) = result { #inner_state.#inner_out_stack.push(result); + } else { + #(#restore_values)* } }, }; tokens.extend(quote! { if true #(&& (#conditions))* { + #(#store_values)* #aux_run } }); diff --git a/src/instructions/logical.rs b/src/instructions/logical.rs index 05c33e4..639b08d 100644 --- a/src/instructions/logical.rs +++ b/src/instructions/logical.rs @@ -7,74 +7,86 @@ use crate::push::state::PushState; use rust_decimal::Decimal; /// Runs logical and on two values -fn _and(vals: Vec) -> Option +fn _and(a: T, b: T) -> Option where - T: Copy + LogicalTrait, + T: LogicalTrait, { - Some(vals[0].logical_and(vals[1])) + Some(b.logical_and(a)) } -make_instruction!(boolean, boolean, _and, bool, 2); /// Runs logical or on two values -fn _or(vals: Vec) -> Option +fn _or(a: T, b: T) -> Option where - T: Copy + LogicalTrait, + T: LogicalTrait, { - Some(vals[0].logical_or(vals[1])) + Some(b.logical_or(a)) } -make_instruction!(boolean, boolean, _or, bool, 2); /// Runs logical not on two values -fn _not(vals: Vec) -> Option +fn _not(a: T) -> Option where - T: Copy + LogicalTrait, + T: LogicalTrait, { - Some(vals[0].logical_not()) + Some(a.logical_not()) } -make_instruction!(boolean, boolean, _not, bool, 1); /// Runs logical xor on two values -fn _xor(vals: Vec) -> Option +fn _xor(a: T, b: T) -> Option where - T: Copy + LogicalTrait, + T: LogicalTrait, { - Some(vals[0].logical_xor(vals[1])) + Some(b.logical_xor(a)) } -make_instruction!(boolean, boolean, _xor, bool, 2); /// Inverts the first value and runs logical and on two values -fn _invert_first_then_and(vals: Vec) -> Option +fn _invert_first_then_and(a: T, b: T) -> Option where - T: Copy + LogicalTrait, + T: LogicalTrait, { - Some(vals[0].logical_not().logical_and(vals[1])) + Some(a.logical_not().logical_and(b)) } -make_instruction!(boolean, boolean, _invert_first_then_and, bool, 2); /// Inverts the second value and runs logical and on two values -fn _invert_second_then_and(vals: Vec) -> Option +fn _invert_second_then_and(a: T, b: T) -> Option where - T: Copy + LogicalTrait, + T: LogicalTrait, { - Some(vals[0].logical_and(vals[1].logical_not())) + Some(a.logical_and(b.logical_not())) } -make_instruction!(boolean, boolean, _invert_second_then_and, bool, 2); -fn _from_int(vals: Vec) -> Option +fn _from_int(a: i128) -> Option where - T: Copy + CastingTrait, + T: CastingTrait, { - T::from_int(vals[0]) + T::from_int(a) } -make_instruction_out!(int, boolean, _from_int, i128, 1); -fn _from_float(vals: Vec) -> Option +fn _from_float(a: Decimal) -> Option where - T: Copy + CastingTrait, + T: CastingTrait, { - T::from_float(vals[0]) + T::from_float(a) } -make_instruction_out!(float, boolean, _from_float, Decimal, 1); + +macro_rules! make_logical_instructions { + ($stack:ident) => { + make_instruction_new!(_and, $stack, $stack, $stack, $stack); + make_instruction_new!(_or, $stack, $stack, $stack, $stack); + make_instruction_new!(_not, $stack, $stack, $stack); + make_instruction_new!(_xor, $stack, $stack, $stack, $stack); + make_instruction_new!(_invert_first_then_and, $stack, $stack, $stack, $stack); + make_instruction_new!(_invert_second_then_and, $stack, $stack, $stack, $stack); + make_instruction_new!(_from_int, $stack, $stack, int); + make_instruction_new!(_from_float, $stack, $stack, float); + }; +} + +macro_rules! all_logical_instructions { + () => { + make_logical_instructions!(boolean); + }; +} +all_logical_instructions!(); #[cfg(test)] mod tests { diff --git a/src/instructions/mod.rs b/src/instructions/mod.rs index e8c6851..327b4c3 100644 --- a/src/instructions/mod.rs +++ b/src/instructions/mod.rs @@ -1,11 +1,3 @@ -use crate::instructions::code::*; -use crate::instructions::common::*; -use crate::instructions::logical::*; -use crate::instructions::numeric::*; -use crate::instructions::vector::*; -use crate::push::state::PushState; -use rush_macro::run_instruction; - #[macro_use] pub mod macros { /// A macro that makes a push instruction given: the name of the input stack to use, @@ -305,7 +297,7 @@ pub mod macros { }; } - /// Runs a function and ensures needed variables are extracted from a state without error + /// Runs a function and ensures the necessary variables are extracted from a state without error macro_rules! make_instruction_new { ($func:ident, $prefix:ident, $out_stack:ident, $($stacks:ident), *) => { paste::item! { @@ -338,8 +330,8 @@ pub mod vector; #[cfg(test)] mod tests { - use super::*; - use crate::push::state::EMPTY_STATE; + //use super::*; + use crate::push::state::{EMPTY_STATE, PushState}; #[test] fn make_instruction_new_test() { diff --git a/src/instructions/numeric.rs b/src/instructions/numeric.rs index 66c4ed3..a9823e0 100644 --- a/src/instructions/numeric.rs +++ b/src/instructions/numeric.rs @@ -45,269 +45,249 @@ where } /// Takes the remainder of two values -fn _rem(vals: Vec) -> Option +fn _rem(a: T, b: T) -> Option where T: Div + Copy + NumericTrait, { - vals[1].checked_mod(vals[0]) + b.checked_mod(a) } -make_instruction!(int, int, _rem, i128, 2); -make_instruction!(float, float, _rem, Decimal, 2); /// Takes the max of two values -fn _max(vals: Vec) -> Option +fn _max(a: T, b: T) -> Option where - T: Ord + Copy, + T: Ord, { - Some(max(vals[1], vals[0])) + Some(max(a, b)) } -make_instruction!(int, int, _max, i128, 2); -make_instruction!(float, float, _max, Decimal, 2); /// Takes the min of two values -fn _min(vals: Vec) -> Option +fn _min(a: T, b: T) -> Option where - T: Ord + Copy, + T: Ord, { - Some(min(vals[1], vals[0])) + Some(min(a, b)) } -make_instruction!(int, int, _min, i128, 2); -make_instruction!(float, float, _min, Decimal, 2); /// Increments a single value by 1 -fn _inc(vals: Vec) -> Option +fn _inc(a: T) -> Option where T: NumericTrait + Copy, { - Some(vals[0].increment()) + Some(a.increment()) } -make_instruction!(int, int, _inc, i128, 1); -make_instruction!(float, float, _inc, Decimal, 1); /// Decrements a single value by 1 -fn _dec(vals: Vec) -> Option +fn _dec(a: T) -> Option where - T: NumericTrait + Copy, + T: NumericTrait, { - Some(vals[0].decrement()) + Some(a.decrement()) } -make_instruction!(int, int, _dec, i128, 1); -make_instruction!(float, float, _dec, Decimal, 1); /// Checks if the 2nd to top value is less than the top value -fn _lt(vals: Vec) -> Option +fn _lt(a: T, b: T) -> Option where - T: Ord + Copy, + T: Ord, { - Some(vals[1] < vals[0]) + Some(b < a) } -make_instruction!(int, boolean, _lt, i128, 2); -make_instruction!(float, boolean, _lt, Decimal, 2); /// Checks if the 2nd to top value is greater than the top value -fn _gt(vals: Vec) -> Option +fn _gt(a: T, b: T) -> Option where - T: Ord + Copy, + T: Ord, { - Some(vals[1] > vals[0]) + Some(b > a) } -make_instruction!(int, boolean, _gt, i128, 2); -make_instruction!(float, boolean, _gt, Decimal, 2); /// Checks if the 2nd to top value is less than or equal to the top value -fn _lte(vals: Vec) -> Option +fn _lte(a: T, b: T) -> Option where T: Ord + Copy, { - Some(vals[1] <= vals[0]) + Some(b <= a) } -make_instruction!(int, boolean, _lte, i128, 2); -make_instruction!(float, boolean, _lte, Decimal, 2); /// Checks if the 2nd to top value is greater than or equal to the top value -fn _gte(vals: Vec) -> Option +fn _gte(a: T, b: T) -> Option where - T: Ord + Copy, + T: Ord, { - Some(vals[1] >= vals[0]) + Some(b >= a) } -make_instruction!(int, boolean, _gte, i128, 2); -make_instruction!(float, boolean, _gte, Decimal, 2); /// Runs sin on a single item. -fn _sin(vals: Vec) -> Option +fn _sin(a: T) -> Option where - T: Copy + NumericTrait, + T: NumericTrait, { - vals[0].safe_sin() + a.safe_sin() } -make_instruction!(int, int, _sin, i128, 1); -make_instruction!(float, float, _sin, Decimal, 1); /// Runs arcsin on a single item. -fn _arcsin(vals: Vec) -> Option +fn _arcsin(a: T) -> Option where - T: Copy + NumericTrait, + T: NumericTrait, { - vals[0].safe_sin()?.inverse() + a.safe_sin()?.inverse() } -make_instruction!(int, int, _arcsin, i128, 1); -make_instruction!(float, float, _arcsin, Decimal, 1); /// Runs cos on a single item. -fn _cos(vals: Vec) -> Option +fn _cos(a: T) -> Option where - T: Copy + NumericTrait, + T: NumericTrait, { - vals[0].safe_cos() + a.safe_cos() } -make_instruction!(int, int, _cos, i128, 1); -make_instruction!(float, float, _cos, Decimal, 1); /// Runs arcsin on a single item. -fn _arccos(vals: Vec) -> Option +fn _arccos(a: T) -> Option where - T: Copy + NumericTrait, + T: NumericTrait, { - vals[0].safe_cos()?.inverse() + a.safe_cos()?.inverse() } -make_instruction!(int, int, _arccos, i128, 1); -make_instruction!(float, float, _arccos, Decimal, 1); /// Runs tan on a single item. -fn _tan(vals: Vec) -> Option +fn _tan(a: T) -> Option where - T: Copy + NumericTrait, + T: NumericTrait, { - vals[0].safe_tan() + a.safe_tan() } -make_instruction!(int, int, _tan, i128, 1); -make_instruction!(float, float, _tan, Decimal, 1); /// Runs arctan on a single item. -fn _arctan(vals: Vec) -> Option +fn _arctan(a: T) -> Option where - T: Copy + NumericTrait, + T: NumericTrait, { - vals[0].safe_tan()?.inverse() + a.safe_tan()?.inverse() +} + +/// Converts a single value from an int to an arbitrary type. +fn _from_int(a: i128) -> Option +where + T: CastingTrait, +{ + T::from_int(a) } -make_instruction!(int, int, _arctan, i128, 1); -make_instruction!(float, float, _arctan, Decimal, 1); /// Converts a single value from a float to an arbitrary type. -fn _from_int(vals: Vec) -> Option +fn _from_float(a: Decimal) -> Option where - T: Copy + CastingTrait, + T: CastingTrait, { - T::from_int(vals[0]) + T::from_float(a) } -make_instruction_out!(int, float, _from_int, i128, 1); -/// Converts a single value from a float to an arbitrary type. -fn _from_float(vals: Vec) -> Option +/// Converts a bool to a new type. +fn _from_boolean(a: bool) -> Option where - T: Copy + CastingTrait, + T: CastingTrait, { - T::from_float(vals[0]) + T::from_bool(a) } -make_instruction_out!(float, int, _from_float, Decimal, 1); -/// Converts a bool to a to a new type. -fn _from_boolean(vals: Vec) -> Option -where - T: Copy + CastingTrait, -{ - T::from_bool(vals[0]) -} -make_instruction_out!(boolean, int, _from_boolean, bool, 1); -make_instruction_out!(boolean, float, _from_boolean, bool, 1); - -/// Takes the log base 10 of a single Decimal. Acts as a +/// Takes log base 10 of a single Decimal. Acts as a /// NoOp if the value is 0. If the value is negative, takes /// the absolute value of the number. -fn _log(vals: Vec) -> Option +fn _log(a: T) -> Option where - T: Copy + NumericTrait, + T: NumericTrait, { - vals[0].absolute().safe_log10() + a.absolute().safe_log10() } -make_instruction!(int, int, _log, i128, 1); -make_instruction!(float, float, _log, Decimal, 1); /// Takes the exp of a single value. Ints get truncated. -fn _exp(vals: Vec) -> Option +fn _exp(a: T) -> Option where - T: Copy + NumericTrait, + T: NumericTrait, { - vals[0].safe_exp() + a.safe_exp() } -make_instruction!(int, int, _exp, i128, 1); -make_instruction!(float, float, _exp, Decimal, 1); /// Takes the square root of the absolute value of a single value. -fn _sqrt(vals: Vec) -> Option +fn _sqrt(a: T) -> Option where - T: Copy + NumericTrait, + T: NumericTrait, { - vals[0].safe_sqrt() + a.safe_sqrt() } -make_instruction!(int, int, _sqrt, i128, 1); -make_instruction!(float, float, _sqrt, Decimal, 1); /// Takes the inverse of a single value. If the number is 0, /// does nothing (returns None). Truncates an int to 0. -fn _inv(vals: Vec) -> Option +fn _inv(a: T) -> Option where - T: Copy + NumericTrait, + T: NumericTrait, { - vals[0].inverse() + a.inverse() } -make_instruction!(int, int, _inv, i128, 1); -make_instruction!(float, float, _inv, Decimal, 1); /// Takes the absolute value of the top number -fn _abs(vals: Vec) -> Option +fn _abs(a: T) -> Option where - T: Copy + NumericTrait, + T: NumericTrait, { - Some(vals[0].absolute()) + Some(a.absolute()) } -make_instruction!(int, int, _abs, i128, 1); -make_instruction!(float, float, _abs, Decimal, 1); /// Reverses the sign of the top number -fn _sign_reverse(vals: Vec) -> Option +fn _sign_reverse(a: T) -> Option where - T: Copy + NumericTrait, + T: NumericTrait, { - Some(vals[0].sign_reverse()) + Some(a.sign_reverse()) } -make_instruction!(int, int, _sign_reverse, i128, 1); -make_instruction!(float, float, _sign_reverse, Decimal, 1); /// Squares the top number -fn _square(vals: Vec) -> Option +fn _square(a: T) -> Option where - T: Copy + NumericTrait, + T: NumericTrait, { - Some(vals[0].square()) + Some(a.square()) } -make_instruction!(int, int, _square, i128, 1); -make_instruction!(float, float, _square, Decimal, 1); -macro_rules! make_instructions { +macro_rules! make_numeric_instructions { ($stack:ident) => { - paste::item! { - make_instruction_new!(_add, $stack, $stack, $stack, $stack); - make_instruction_new!(_sub, $stack, $stack, $stack, $stack); - make_instruction_new!(_mult, $stack, $stack, $stack, $stack); - make_instruction_new!(_div, $stack, $stack, $stack, $stack); - } + make_instruction_new!(_add, $stack, $stack, $stack, $stack); + make_instruction_new!(_sub, $stack, $stack, $stack, $stack); + make_instruction_new!(_mult, $stack, $stack, $stack, $stack); + make_instruction_new!(_div, $stack, $stack, $stack, $stack); + make_instruction_new!(_rem, $stack, $stack, $stack, $stack); + make_instruction_new!(_max, $stack, $stack, $stack, $stack); + make_instruction_new!(_min, $stack, $stack, $stack, $stack); + make_instruction_new!(_inc, $stack, $stack, $stack); + make_instruction_new!(_dec, $stack, $stack, $stack); + make_instruction_new!(_lt, $stack, boolean, $stack, $stack); + make_instruction_new!(_gt, $stack, boolean, $stack, $stack); + make_instruction_new!(_lte, $stack, boolean, $stack, $stack); + make_instruction_new!(_gte, $stack, boolean, $stack, $stack); + make_instruction_new!(_sin, $stack, $stack, $stack); + make_instruction_new!(_arcsin, $stack, $stack, $stack); + make_instruction_new!(_cos, $stack, $stack, $stack); + make_instruction_new!(_arccos, $stack, $stack, $stack); + make_instruction_new!(_tan, $stack, $stack, $stack); + make_instruction_new!(_arctan, $stack, $stack, $stack); + make_instruction_new!(_from_boolean, $stack, $stack, boolean); + make_instruction_new!(_log, $stack, $stack, $stack); + make_instruction_new!(_exp, $stack, $stack, $stack); + make_instruction_new!(_sqrt, $stack, $stack, $stack); + make_instruction_new!(_inv, $stack, $stack, $stack); + make_instruction_new!(_abs, $stack, $stack, $stack); + make_instruction_new!(_sign_reverse, $stack, $stack, $stack); + make_instruction_new!(_square, $stack, $stack, $stack); }; } -make_instructions!(int); -make_instructions!(float); +macro_rules! all_numeric_instructions { + () => { + make_numeric_instructions!(int); + make_numeric_instructions!(float); + make_instruction_new!(_from_int, float, float, int); + make_instruction_new!(_from_float, int, int, float); + }; +} +all_numeric_instructions!(); #[cfg(test)] mod tests { @@ -348,124 +328,70 @@ mod tests { /// Tests the _rem function #[test] fn rem_test() { - let vals: Vec = vec![3, 20]; - assert_eq!(Some(2), _rem(vals)); - - let vals: Vec = vec![20, 20]; - assert_eq!(Some(0), _rem(vals)); - - let vals: Vec = vec![0, 9]; - assert_eq!(None, _rem(vals)); + assert_eq!(Some(2), _rem(3, 20)); + assert_eq!(Some(0), _rem(20, 20)); + assert_eq!(None, _rem(0, 9)); } /// Tests the _max function #[test] fn max_test() { - let vals: Vec = vec![1, 2]; - assert_eq!(Some(2), _max(vals)); - - let vals: Vec = vec![3, 0]; - assert_eq!(Some(3), _max(vals)); - - let vals: Vec = vec![dec!(2.2), dec!(1.1)]; - assert_eq!(Some(dec!(2.2)), _max(vals)); - - let vals: Vec = vec![dec!(3.3), dec!(-1.1)]; - assert_eq!(Some(dec!(3.3)), _max(vals)); + assert_eq!(Some(2), _max(1, 2)); + assert_eq!(Some(3), _max(3, 0)); + assert_eq!(Some(dec!(2.2)), _max(dec!(2.2), dec!(1.1))); + assert_eq!(Some(dec!(3.3)), _max(dec!(3.3), dec!(-1.1))); } /// Tests the _min function #[test] fn min_test() { - let vals: Vec = vec![1, 2]; - assert_eq!(Some(1), _min(vals)); - - let vals: Vec = vec![3, 0]; - assert_eq!(Some(0), _min(vals)); - - let vals: Vec = vec![dec!(2.2), dec!(1.1)]; - assert_eq!(Some(dec!(1.1)), _min(vals)); - - let vals: Vec = vec![dec!(3.3), dec!(-1.1)]; - assert_eq!(Some(dec!(-1.1)), _min(vals)); + assert_eq!(Some(1), _min(1, 2)); + assert_eq!(Some(0), _min(3, 0)); + assert_eq!(Some(dec!(1.1)), _min(dec!(2.2), dec!(1.1))); + assert_eq!(Some(dec!(-1.1)), _min(dec!(3.3), dec!(-1.1))); } /// Tests the _inc and _dec functions #[test] fn inc_dec_test() { - let vals: Vec = vec![2]; - assert_eq!(Some(3), _inc(vals)); - - let vals: Vec = vec![10]; - assert_eq!(Some(9), _dec(vals)); - - let vals: Vec = vec![dec!(2.2)]; - assert_eq!(Some(dec!(3.2)), _inc(vals)); - - let vals: Vec = vec![dec!(5.6)]; - assert_eq!(Some(dec!(4.6)), _dec(vals)); + assert_eq!(Some(3), _inc(2)); + assert_eq!(Some(9), _dec(10)); + assert_eq!(Some(dec!(3.2)), _inc(dec!(2.2))); + assert_eq!(Some(dec!(4.6)), _dec(dec!(5.6))); } /// Tests the _lt, _gt, _lte, and _gte functions #[test] fn lt_gt_lte_gte_test() { - let vals: Vec = vec![3, 2]; - assert_eq!(Some(true), _lt(vals)); - - let vals: Vec = vec![1, 4]; - assert_eq!(Some(false), _lt(vals)); - - let vals: Vec = vec![3, 3]; - assert_eq!(Some(false), _lt(vals)); - - let vals: Vec = vec![2, 3]; - assert_eq!(Some(true), _gt(vals)); - - let vals: Vec = vec![4, 1]; - assert_eq!(Some(false), _gt(vals)); - - let vals: Vec = vec![3, 3]; - assert_eq!(Some(false), _gt(vals)); - - let vals: Vec = vec![3, 2]; - assert_eq!(Some(true), _lte(vals)); - - let vals: Vec = vec![1, 4]; - assert_eq!(Some(false), _lte(vals)); - - let vals: Vec = vec![3, 3]; - assert_eq!(Some(true), _lte(vals)); - - let vals: Vec = vec![2, 3]; - assert_eq!(Some(true), _gte(vals)); - - let vals: Vec = vec![4, 1]; - assert_eq!(Some(false), _gte(vals)); - - let vals: Vec = vec![3, 3]; - assert_eq!(Some(true), _gte(vals)); + assert_eq!(Some(true), _lt(3, 2)); + assert_eq!(Some(false), _lt(1, 4)); + assert_eq!(Some(false), _lt(3, 3)); + assert_eq!(Some(true), _gt(2, 3)); + assert_eq!(Some(false), _gt(4, 1)); + assert_eq!(Some(false), _gt(3, 3)); + assert_eq!(Some(true), _lte(3, 2)); + assert_eq!(Some(false), _lte(1, 4)); + assert_eq!(Some(true), _lte(3, 3)); + assert_eq!(Some(true), _gte(2, 3)); + assert_eq!(Some(false), _gte(4, 1)); + assert_eq!(Some(true), _gte(3, 3)); } /// Tests the various trig functions. #[test] fn trig_tests() { - let vals = vec![Decimal::PI]; - assert_eq!(Some(dec!(0.0)), _sin(vals)); - - let vals = vec![Decimal::QUARTER_PI]; - assert_eq!(Some(dec!(1.4142135623869512272301701717)), _arcsin(vals)); - - let vals = vec![Decimal::PI]; - assert_eq!(Some(dec!(-1.0)), _cos(vals)); - - let vals = vec![Decimal::QUARTER_PI]; - assert_eq!(Some(dec!(1.4142135626023406165042434783)), _arccos(vals)); - - let vals = vec![Decimal::PI]; - assert_eq!(Some(dec!(0.0)), _tan(vals)); - - let vals = vec![Decimal::QUARTER_PI]; - assert_eq!(Some(dec!(1.0000000043184676055890307049)), _arctan(vals)); + assert_eq!(Some(dec!(0.0)), _sin(Decimal::PI)); + assert_eq!( + Some(dec!(1.4142135623869512272301701717)), + _arcsin(Decimal::QUARTER_PI) + ); + assert_eq!(Some(dec!(-1.0)), _cos(Decimal::PI)); + assert_eq!(Some(dec!(-1.0)), _arccos(Decimal::PI)); + assert_eq!(Some(dec!(0.0)), _tan(Decimal::PI)); + assert_eq!( + Some(dec!(1.0000000043184676055890307049)), + _arctan(Decimal::QUARTER_PI) + ); } /// Tests that the various addition functions. @@ -714,6 +640,13 @@ mod tests { test_state.float = vec![dec!(2.1)]; int_from_float(&mut test_state); assert_eq!(vec![2], test_state.int); + test_state.float.clear(); + test_state.int.clear(); + + test_state.boolean = vec![true]; + int_from_boolean(&mut test_state); + assert_eq!(vec![1], test_state.int); + test_state.boolean.clear(); } /// Tests the log function