diff --git a/src/instructions/mod.rs b/src/instructions/mod.rs index e2356be..d056755 100644 --- a/src/instructions/mod.rs +++ b/src/instructions/mod.rs @@ -12,7 +12,8 @@ pub mod macros { /// int stack is type: *Vec*. `fn_type` is *i128* in this case. /// The `fn_arity` argument refers to how many popped stack items are needed to /// execute the instruction. If the amount of items in the stack is less than - /// this value, the instruction does nothing. + /// this value, the instruction does nothing. How many items exactly should be passed + /// as a list to the functions used for calculations. /// /// What causes an instruction to NoOp: /// 1) There aren't enough values on a stack to execute an instruction. @@ -59,7 +60,7 @@ pub mod macros { } let mut inputs: Vec<$fn_type> = Vec::with_capacity($fn_arity); for n in 1..=$fn_arity { - inputs.push(state.$in_stack[in_stack_len - n]); + inputs.push(state.$in_stack[in_stack_len - n].clone()); } if let Some(result) = $fn_name(inputs) { for _ in 0..$fn_arity { @@ -81,6 +82,7 @@ pub mod macros { paste::item! { /// Runs the $fn_name function on the top $fn_arity items from /// the $in_stack and places the calculated value on the $out_stack. + #[allow(clippy::reversed_empty_ranges)] pub fn [< $in_stack $fn_name >] (state: &mut PushState) { let in_stack_len = state.$in_stack.len(); if in_stack_len < $fn_arity { @@ -174,18 +176,67 @@ pub mod macros { } let mut inputs: Vec<$fn_type> = Vec::with_capacity($fn_arity); let mut aux_inputs: Vec<$aux_type> = Vec::with_capacity($aux_arity); - for n in 1..=$fn_arity { - inputs.push(state.$in_stack[in_stack_len - n].clone()); - } for n in 1..=$aux_arity { aux_inputs.push(state.$aux_stack[aux_stack_len - n].clone()); } + for n in 1..=$fn_arity { + inputs.push(state.$in_stack[in_stack_len - n].clone()); + } if let Some(result) = $fn_name(inputs, aux_inputs) { + for _ in 0..$aux_arity { + state.$aux_stack.pop(); + } for _ in 0..$fn_arity { state.$in_stack.pop(); } - for _ in 0..$aux_arity { - state.$aux_stack.pop(); + state.$out_stack.push(result); + } + } + } + }; + } + + /// Same as `make_instruction!` but can work on two auxiliary stacks. Is there a way + /// to generalize even this? + /// + /// `aux_stack` is an auxiliary stack to be used as input to internal function. + /// `aux_arity` is the amount of the auxiliary stack to use. + /// `aux_type` is the type of the auxiliary stack + #[macro_export] + macro_rules! make_instruction_aux2 { + ($in_stack:ident, $out_stack:ident, $fn_name:ident, $fn_type:ty, $fn_arity:stmt, $aux0_stack:ident, $aux0_arity:stmt, $aux0_type:ty, $aux1_stack:ident, $aux1_arity:stmt, $aux1_type:ty) => { + paste::item! { + /// Runs the $fn_name function on the top $fn_arity items from + /// the $in_stack and places the calculated value on the $out_stack. + /// $aux_stack is also used and popped $aux_arity time(s). + pub fn [< $in_stack $fn_name >] (state: &mut PushState) { + let in_stack_len = state.$in_stack.len(); + let aux0_stack_len = state.$aux0_stack.len(); + let aux1_stack_len = state.$aux1_stack.len(); + if in_stack_len < $fn_arity || aux0_stack_len < $aux0_arity || aux1_stack_len < $aux1_arity { + return; + } + let mut inputs: Vec<$fn_type> = Vec::with_capacity($fn_arity); + let mut aux0_inputs: Vec<$aux0_type> = Vec::with_capacity($aux0_arity); + let mut aux1_inputs: Vec<$aux1_type> = Vec::with_capacity($aux1_arity); + for n in 1..=$aux0_arity { + aux0_inputs.push(state.$aux0_stack[aux0_stack_len - n].clone()); + } + for n in 1..=$aux1_arity { + aux1_inputs.push(state.$aux1_stack[aux1_stack_len - n].clone()); + } + for n in 1..=$fn_arity { + inputs.push(state.$in_stack[in_stack_len - n].clone()); + } + if let Some(result) = $fn_name(inputs, aux0_inputs, aux1_inputs) { + for _ in 0..$aux0_arity { + state.$aux0_stack.pop(); + } + for _ in 0..$aux1_arity { + state.$aux1_stack.pop(); + } + for _ in 0..$fn_arity { + state.$in_stack.pop(); } state.$out_stack.push(result); } diff --git a/src/instructions/vector.rs b/src/instructions/vector.rs index aac69e7..8fbb409 100644 --- a/src/instructions/vector.rs +++ b/src/instructions/vector.rs @@ -1,6 +1,13 @@ use crate::push::state::PushState; use rust_decimal::Decimal; +use std::collections::VecDeque; +/// Generates an index between 0 and length. Takes abs(num) and then mods it by length. +fn bounded_idx(num: i128, length: usize) -> usize { + (num.unsigned_abs() as usize) % length +} + +/// Concats two vectors together. pub fn _concat(vals: Vec>) -> Option> where T: Clone, @@ -16,9 +23,599 @@ make_instruction_clone!(vector_boolean, vector_boolean, _concat, Vec, 2); make_instruction_clone!(vector_char, vector_char, _concat, Vec, 2); make_instruction_clone!(string, string, _concat, Vec, 2); -pub fn _conj(vals: Vec>) -> Option> { - None // @TODO: This gonna need new instruction macros. Tomorrow issue. +/// Prepends a primitive value to a vector. +pub fn _conj(vec_vals: Vec>, prim_vals: Vec) -> Option> +where + T: Clone, +{ + let mut t_vec = vec_vals[0].clone(); + t_vec.insert(0, prim_vals[0].clone()); + Some(t_vec) } +make_instruction_aux!(vector_int, vector_int, _conj, Vec, 1, int, 1, i128); +make_instruction_aux!( + vector_float, + vector_float, + _conj, + Vec, + 1, + float, + 1, + Decimal +); +make_instruction_aux!( + vector_string, + vector_string, + _conj, + Vec>, + 1, + string, + 1, + Vec +); +make_instruction_aux!( + vector_boolean, + vector_boolean, + _conj, + Vec, + 1, + boolean, + 1, + bool +); +make_instruction_aux!(vector_char, vector_char, _conj, Vec, 1, char, 1, char); +make_instruction_aux!(string, string, _conj, Vec, 1, char, 1, char); + +/// Appends a primitive value to a vector. +pub fn _conj_end(vec_vals: Vec>, prim_vals: Vec) -> Option> +where + T: Clone, +{ + let mut t_vec = vec_vals[0].clone(); + t_vec.push(prim_vals[0].clone()); + Some(t_vec) +} +make_instruction_aux!( + vector_int, + vector_int, + _conj_end, + Vec, + 1, + int, + 1, + i128 +); +make_instruction_aux!( + vector_float, + vector_float, + _conj_end, + Vec, + 1, + float, + 1, + Decimal +); +make_instruction_aux!( + vector_string, + vector_string, + _conj_end, + Vec>, + 1, + string, + 1, + Vec +); +make_instruction_aux!( + vector_boolean, + vector_boolean, + _conj_end, + Vec, + 1, + boolean, + 1, + bool +); +make_instruction_aux!( + vector_char, + vector_char, + _conj_end, + Vec, + 1, + char, + 1, + char +); +make_instruction_aux!(string, string, _conj_end, Vec, 1, char, 1, char); + +/// Takes the first N items from a vector. N based on an int. +pub fn _take_n(vals: Vec>, auxs: Vec) -> Option> +where + T: Clone, +{ + let ret_vec = vals[0].clone(); + if ret_vec.is_empty() { + return None; + } + Some(ret_vec[0..bounded_idx(auxs[0], ret_vec.len())].to_vec()) +} +make_instruction_aux!(vector_int, vector_int, _take_n, Vec, 1, int, 1, i128); +make_instruction_aux!( + vector_float, + vector_float, + _take_n, + Vec, + 1, + int, + 1, + i128 +); +make_instruction_aux!( + vector_string, + vector_string, + _take_n, + Vec>, + 1, + int, + 1, + i128 +); +make_instruction_aux!( + vector_boolean, + vector_boolean, + _take_n, + Vec, + 1, + int, + 1, + i128 +); +make_instruction_aux!( + vector_char, + vector_char, + _take_n, + Vec, + 1, + int, + 1, + i128 +); +make_instruction_aux!(string, string, _take_n, Vec, 1, int, 1, i128); + +/// Takes the first N items from a vector. N based on an int. +pub fn _take_last_n(vals: Vec>, auxs: Vec) -> Option> +where + T: Clone, +{ + let ret_vec = vals[0].clone(); + if ret_vec.is_empty() { + return None; + } + let ret_vec_len = ret_vec.len(); + Some(ret_vec[ret_vec_len - bounded_idx(auxs[0], ret_vec_len)..ret_vec_len].to_vec()) +} +make_instruction_aux!( + vector_int, + vector_int, + _take_last_n, + Vec, + 1, + int, + 1, + i128 +); +make_instruction_aux!( + vector_float, + vector_float, + _take_last_n, + Vec, + 1, + int, + 1, + i128 +); +make_instruction_aux!( + vector_string, + vector_string, + _take_last_n, + Vec>, + 1, + int, + 1, + i128 +); +make_instruction_aux!( + vector_boolean, + vector_boolean, + _take_last_n, + Vec, + 1, + int, + 1, + i128 +); +make_instruction_aux!( + vector_char, + vector_char, + _take_last_n, + Vec, + 1, + int, + 1, + i128 +); +make_instruction_aux!(string, string, _take_last_n, Vec, 1, int, 1, i128); + +/// Takes a sublist of a vector based on two ints. +pub fn _sub(vals: Vec>, auxs: Vec) -> Option> +where + T: Clone, +{ + let ret_vec = vals[0].clone(); + if ret_vec.is_empty() { + return None; + } + let (mut start, mut end): (usize, usize) = ( + auxs[0].unsigned_abs() as usize, + auxs[1].unsigned_abs() as usize, + ); + if start > end { + (start, end) = (end, start) + } + let fin_start = start.min(ret_vec.len()); + let fin_end = end.min(ret_vec.len()); + Some(ret_vec[fin_start..fin_end].to_vec()) +} +make_instruction_aux!(vector_int, vector_int, _sub, Vec, 1, int, 2, i128); +make_instruction_aux!( + vector_float, + vector_float, + _sub, + Vec, + 1, + int, + 2, + i128 +); +make_instruction_aux!( + vector_string, + vector_string, + _sub, + Vec>, + 1, + int, + 2, + i128 +); +make_instruction_aux!( + vector_boolean, + vector_boolean, + _sub, + Vec, + 1, + int, + 2, + i128 +); +make_instruction_aux!(vector_char, vector_char, _sub, Vec, 1, int, 2, i128); +make_instruction_aux!(string, string, _sub, Vec, 1, int, 2, i128); + +/// Takes the first item from a vector. +pub fn _first(vals: Vec>) -> Option +where + T: Clone, +{ + let ret_vec = vals[0].clone(); + if ret_vec.is_empty() { + return None; + } + Some(vals[0][0].clone()) +} +make_instruction_clone!(vector_int, int, _first, Vec, 1); +make_instruction_clone!(vector_float, float, _first, Vec, 1); +make_instruction_clone!(vector_string, string, _first, Vec>, 1); +make_instruction_clone!(vector_boolean, boolean, _first, Vec, 1); +make_instruction_clone!(vector_char, char, _first, Vec, 1); +make_instruction_clone!(string, char, _first, Vec, 1); + +/// Takes the first item from a vector, wraps it into a vector, and pushes it back +/// to the same stack. +pub fn _from_first_prim(vals: Vec>) -> Option> +where + T: Clone, +{ + let ret_vec = vals[0].clone(); + if ret_vec.is_empty() { + return None; + } + Some(vec![vals[0][0].clone()]) +} +make_instruction_clone!(vector_int, vector_int, _from_first_prim, Vec, 1); +make_instruction_clone!( + vector_float, + vector_float, + _from_first_prim, + Vec, + 1 +); +make_instruction_clone!( + vector_string, + vector_string, + _from_first_prim, + Vec>, + 1 +); +make_instruction_clone!( + vector_boolean, + vector_boolean, + _from_first_prim, + Vec, + 1 +); +make_instruction_clone!(vector_char, vector_char, _from_first_prim, Vec, 1); +make_instruction_clone!(string, string, _from_first_prim, Vec, 1); + +/// Places the top of a primitive type into a vector +pub fn _from_prim(vals: Vec) -> Option> +where + T: Clone, +{ + Some(vec![vals[0].clone()]) +} +make_instruction_out!(int, vector_int, _from_prim, i128, 1); +make_instruction_out!(float, vector_float, _from_prim, Decimal, 1); +make_instruction_out!(string, vector_string, _from_prim, Vec, 1); +make_instruction_out!(boolean, vector_boolean, _from_prim, bool, 1); +make_instruction_out!(char, vector_char, _from_prim, char, 1); +make_instruction_out!(char, string, _from_prim, char, 1); + +/// Takes the last item from a vector. +pub fn _last(vals: Vec>) -> Option +where + T: Clone, +{ + let ret_vec = vals[0].clone(); + if ret_vec.is_empty() { + return None; + } + Some(vals[0][ret_vec.len() - 1].clone()) +} +make_instruction_clone!(vector_int, int, _last, Vec, 1); +make_instruction_clone!(vector_float, float, _last, Vec, 1); +make_instruction_clone!(vector_string, string, _last, Vec>, 1); +make_instruction_clone!(vector_boolean, boolean, _last, Vec, 1); +make_instruction_clone!(vector_char, char, _last, Vec, 1); +make_instruction_clone!(string, char, _last, Vec, 1); + +/// Takes the last item from a vector, wraps it into a vector, and pushes it back +/// to the same stack. +pub fn _from_last_prim(vals: Vec>) -> Option> +where + T: Clone, +{ + let ret_vec = vals[0].clone(); + if ret_vec.is_empty() { + return None; + } + Some(vec![vals[0][ret_vec.len() - 1].clone()]) +} +make_instruction_clone!(vector_int, vector_int, _from_last_prim, Vec, 1); +make_instruction_clone!(vector_float, vector_float, _from_last_prim, Vec, 1); +make_instruction_clone!( + vector_string, + vector_string, + _from_last_prim, + Vec>, + 1 +); +make_instruction_clone!( + vector_boolean, + vector_boolean, + _from_last_prim, + Vec, + 1 +); +make_instruction_clone!(vector_char, vector_char, _from_last_prim, Vec, 1); +make_instruction_clone!(string, string, _from_last_prim, Vec, 1); + +/// Takes the nth item from a vector. N from int stack. +pub fn _nth(vals: Vec>, auxs: Vec) -> Option +where + T: Clone, +{ + let ret_vec = vals[0].clone(); + if ret_vec.is_empty() { + return None; + } + Some(vals[0][bounded_idx(auxs[0], ret_vec.len())].clone()) +} +make_instruction_aux!(vector_int, int, _nth, Vec, 1, int, 1, i128); +make_instruction_aux!(vector_float, float, _nth, Vec, 1, int, 1, i128); +make_instruction_aux!(vector_string, string, _nth, Vec>, 1, int, 1, i128); +make_instruction_aux!(vector_boolean, boolean, _nth, Vec, 1, int, 1, i128); +make_instruction_aux!(vector_char, char, _nth, Vec, 1, int, 1, i128); +make_instruction_aux!(string, char, _nth, Vec, 1, int, 1, i128); + +/// Takes the nth item from a vector, wraps it into a vector, and pushes it back +/// to the same stack. N from int stack +pub fn _from_nth_prim(vals: Vec>, auxs: Vec) -> Option> +where + T: Clone, +{ + let ret_vec = vals[0].clone(); + if ret_vec.is_empty() { + return None; + } + Some(vec![vals[0][bounded_idx(auxs[0], ret_vec.len())].clone()]) +} +make_instruction_aux!( + vector_int, + vector_int, + _from_nth_prim, + Vec, + 1, + int, + 1, + i128 +); +make_instruction_aux!( + vector_float, + vector_float, + _from_nth_prim, + Vec, + 1, + int, + 1, + i128 +); +make_instruction_aux!( + vector_string, + vector_string, + _from_nth_prim, + Vec>, + 1, + int, + 1, + i128 +); +make_instruction_aux!( + vector_boolean, + vector_boolean, + _from_nth_prim, + Vec, + 1, + int, + 1, + i128 +); +make_instruction_aux!( + vector_char, + vector_char, + _from_nth_prim, + Vec, + 1, + int, + 1, + i128 +); +make_instruction_aux!( + string, + vector_char, + _from_nth_prim, + Vec, + 1, + int, + 1, + i128 +); + +/// Takes a vector and removes the first element. +pub fn _rest(vals: Vec>) -> Option> +where + T: Clone, +{ + let ret_vec = vals[0].clone(); + if ret_vec.is_empty() { + return None; + } + Some(ret_vec[1..].to_vec()) +} +make_instruction_clone!(vector_int, vector_int, _rest, Vec, 1); +make_instruction_clone!(vector_float, vector_float, _rest, Vec, 1); +make_instruction_clone!(vector_string, vector_string, _rest, Vec>, 1); +make_instruction_clone!(vector_boolean, vector_boolean, _rest, Vec, 1); +make_instruction_clone!(vector_char, vector_char, _rest, Vec, 1); +make_instruction_clone!(string, string, _rest, Vec, 1); + +/// Takes a vector and removes the last element. +pub fn _but_last(vals: Vec>) -> Option> +where + T: Clone, +{ + let ret_vec = vals[0].clone(); + if ret_vec.is_empty() { + return None; + } + Some(ret_vec[0..ret_vec.len() - 1].to_vec()) +} +make_instruction_clone!(vector_int, vector_int, _but_last, Vec, 1); +make_instruction_clone!(vector_float, vector_float, _but_last, Vec, 1); +make_instruction_clone!(vector_string, vector_string, _but_last, Vec>, 1); +make_instruction_clone!(vector_boolean, vector_boolean, _but_last, Vec, 1); +make_instruction_clone!(vector_char, vector_char, _but_last, Vec, 1); +make_instruction_clone!(string, string, _but_last, Vec, 1); + +/// Removes the first n items from a vector. n from the int stack. +pub fn _drop(vals: Vec>, auxs: Vec) -> Option> +where + T: Clone, +{ + let mut ret_vec = vals[0].clone(); + if ret_vec.is_empty() { + return None; + } + ret_vec.drain(0..auxs[0].abs().min(ret_vec.len() as i128) as usize); + Some(ret_vec) +} +make_instruction_aux!(vector_int, vector_int, _drop, Vec, 1, int, 1, i128); +make_instruction_aux!( + vector_float, + vector_float, + _drop, + Vec, + 1, + int, + 1, + i128 +); +make_instruction_aux!( + vector_string, + vector_string, + _drop, + Vec>, + 1, + int, + 1, + i128 +); +make_instruction_aux!( + vector_boolean, + vector_boolean, + _drop, + Vec, + 1, + int, + 1, + i128 +); +make_instruction_aux!(vector_char, vector_char, _drop, Vec, 1, int, 1, i128); +make_instruction_aux!(string, string, _drop, Vec, 1, int, 1, i128); + +/// Takes the length of a vector. +pub fn _length(vals: Vec>) -> Option { + Some(vals[0].len() as i128) +} +make_instruction_clone!(vector_int, int, _length, Vec, 1); +make_instruction_clone!(vector_float, int, _length, Vec, 1); +make_instruction_clone!(vector_string, int, _length, Vec>, 1); +make_instruction_clone!(vector_boolean, int, _length, Vec, 1); +make_instruction_clone!(vector_char, int, _length, Vec, 1); +make_instruction_clone!(string, int, _length, Vec, 1); + +/// Reverses a vector +pub fn _reverse(vals: Vec>) -> Option> +where + T: Clone, +{ + let mut rev_vec = vals[0].clone(); + rev_vec.reverse(); + Some(rev_vec) +} +make_instruction_clone!(vector_int, vector_int, _reverse, Vec, 1); +make_instruction_clone!(vector_float, vector_float, _reverse, Vec, 1); +make_instruction_clone!(vector_string, vector_string, _reverse, Vec>, 1); +make_instruction_clone!(vector_boolean, vector_boolean, _reverse, Vec, 1); +make_instruction_clone!(vector_char, vector_char, _reverse, Vec, 1); +make_instruction_clone!(string, string, _reverse, Vec, 1); #[cfg(test)] mod tests { @@ -26,8 +623,9 @@ mod tests { use crate::push::state::EMPTY_STATE; #[test] - fn test_vector_concat() { + fn vector_concat_test() { let mut test_state = EMPTY_STATE; + let empty_vec: Vec = vec![]; test_state.vector_int = vec![vec![4, 5, 6], vec![1, 2, 3]]; vector_int_concat(&mut test_state); @@ -36,5 +634,332 @@ mod tests { test_state.string = vec![vec!['s', 't'], vec!['t', 'e']]; string_concat(&mut test_state); assert_eq!(vec![vec!['t', 'e', 's', 't']], test_state.string); + + test_state.vector_int = vec![empty_vec.clone(), empty_vec.clone()]; + vector_int_concat(&mut test_state); + assert_eq!(vec![empty_vec], test_state.vector_int); + } + + #[test] + fn vector_conj_test() { + let mut test_state = EMPTY_STATE; + let empty_vec: Vec = vec![]; + + test_state.vector_int = vec![vec![1, 2, 3]]; + test_state.int = vec![0]; + vector_int_conj(&mut test_state); + assert_eq!(vec![vec![0, 1, 2, 3]], test_state.vector_int); + + test_state.vector_int = vec![empty_vec]; + test_state.int = vec![0]; + vector_int_conj(&mut test_state); + assert_eq!(vec![vec![0]], test_state.vector_int); + } + + #[test] + fn vector_conj_end_test() { + let mut test_state = EMPTY_STATE; + let empty_vec: Vec = vec![]; + + test_state.vector_int = vec![vec![1, 2, 3]]; + test_state.int = vec![0]; + vector_int_conj_end(&mut test_state); + assert_eq!(vec![vec![1, 2, 3, 0]], test_state.vector_int); + + test_state.vector_int = vec![empty_vec]; + test_state.int = vec![0]; + vector_int_conj_end(&mut test_state); + assert_eq!(vec![vec![0]], test_state.vector_int); + } + + /// Tests take_n and take_last_n + #[test] + fn vector_takes_test() { + let mut test_state = EMPTY_STATE; + let empty_vec: Vec = vec![]; + + // n + test_state.vector_int = vec![vec![1, 2, 3]]; + test_state.int = vec![2]; + vector_int_take_n(&mut test_state); + assert_eq!(vec![vec![1, 2]], test_state.vector_int); + + test_state.vector_int = vec![vec![1, 2, 3]]; + test_state.int = vec![0]; + vector_int_take_n(&mut test_state); + assert_eq!(vec![empty_vec.clone()], test_state.vector_int); + + test_state.vector_int = vec![vec![1, 2, 3]]; + test_state.int = vec![-5]; + vector_int_take_n(&mut test_state); + assert_eq!(vec![vec![1, 2]], test_state.vector_int); + + test_state.vector_int = vec![empty_vec.clone()]; + test_state.int = vec![2]; + vector_int_take_n(&mut test_state); + assert_eq!(vec![empty_vec.clone()], test_state.vector_int); + + // last n + test_state.vector_int = vec![vec![1, 2, 3]]; + test_state.int = vec![2]; + vector_int_take_last_n(&mut test_state); + assert_eq!(vec![vec![2, 3]], test_state.vector_int); + + test_state.vector_int = vec![vec![1, 2, 3]]; + test_state.int = vec![0]; + vector_int_take_last_n(&mut test_state); + assert_eq!(vec![empty_vec.clone()], test_state.vector_int); + + test_state.vector_int = vec![vec![1, 2, 3]]; + test_state.int = vec![-5]; + vector_int_take_last_n(&mut test_state); + assert_eq!(vec![vec![2, 3]], test_state.vector_int); + + test_state.vector_int = vec![empty_vec.clone()]; + test_state.int = vec![2]; + vector_int_take_last_n(&mut test_state); + assert_eq!(vec![empty_vec.clone()], test_state.vector_int); + } + + #[test] + fn vector_sub_test() { + let mut test_state = EMPTY_STATE; + let empty_vec: Vec = vec![]; + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5]]; + test_state.int = vec![1, 4]; + vector_int_sub(&mut test_state); + assert_eq!(vec![vec![1, 2, 3]], test_state.vector_int); + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5]]; + test_state.int = vec![1, 10]; + vector_int_sub(&mut test_state); + assert_eq!(vec![vec![1, 2, 3, 4, 5]], test_state.vector_int); + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5]]; + test_state.int = vec![-1, 4]; + vector_int_sub(&mut test_state); + assert_eq!(vec![vec![1, 2, 3]], test_state.vector_int); + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5]]; + test_state.int = vec![-4, -1]; + vector_int_sub(&mut test_state); + assert_eq!(vec![vec![1, 2, 3]], test_state.vector_int); + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5]]; + test_state.int = vec![0, 0]; + vector_int_sub(&mut test_state); + assert_eq!(vec![empty_vec.clone()], test_state.vector_int); + + test_state.vector_int = vec![empty_vec.clone()]; + test_state.int = vec![2, 6]; + vector_int_sub(&mut test_state); + assert_eq!(vec![empty_vec.clone()], test_state.vector_int); + + test_state.vector_int = vec![vec![0]]; + test_state.int = vec![2, 10]; + vector_int_sub(&mut test_state); + assert_eq!(vec![empty_vec], test_state.vector_int); + } + + #[test] + fn vector_first_test() { + let mut test_state = EMPTY_STATE; + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5]]; + vector_int_first(&mut test_state); + assert_eq!(vec![0], test_state.int); + + test_state.string = vec![vec!['t', 'e', 's', 't']]; + string_first(&mut test_state); + assert_eq!(vec!['t'], test_state.char); + + let empty_vec: Vec = vec![]; + test_state.vector_int = vec![empty_vec.clone()]; + vector_int_first(&mut test_state); + assert_eq!(vec![empty_vec], test_state.vector_int); + } + + #[test] + fn vector_from_first_prim_test() { + let mut test_state = EMPTY_STATE; + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5]]; + vector_int_from_first_prim(&mut test_state); + assert_eq!(vec![vec![0]], test_state.vector_int); + + let empty_vec = vec![]; + test_state.vector_int = vec![empty_vec.clone()]; + vector_int_from_first_prim(&mut test_state); + assert_eq!(vec![empty_vec], test_state.vector_int); + } + + #[test] + fn vector_from_prim_test() { + let mut test_state = EMPTY_STATE; + + test_state.int = vec![1, 2]; + vector_int_from_prim(&mut test_state); + assert_eq!(vec![vec![2]], test_state.vector_int); + } + + #[test] + fn vector_last_test() { + let mut test_state = EMPTY_STATE; + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5]]; + vector_int_last(&mut test_state); + assert_eq!(vec![5], test_state.int); + + test_state.string = vec![vec!['t', 'e', 's', 't', 's']]; + string_last(&mut test_state); + assert_eq!(vec!['s'], test_state.char); + + let empty_vec: Vec = vec![]; + test_state.vector_int = vec![empty_vec.clone()]; + vector_int_last(&mut test_state); + assert_eq!(vec![empty_vec], test_state.vector_int); + } + + #[test] + fn vector_from_last_prim_test() { + let mut test_state = EMPTY_STATE; + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5]]; + vector_int_from_last_prim(&mut test_state); + assert_eq!(vec![vec![5]], test_state.vector_int); + + let empty_vec = vec![]; + test_state.vector_int = vec![empty_vec.clone()]; + vector_int_from_last_prim(&mut test_state); + assert_eq!(vec![empty_vec], test_state.vector_int); + } + + #[test] + fn vector_nth_test() { + let mut test_state = EMPTY_STATE; + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5]]; + test_state.int = vec![2]; + vector_int_nth(&mut test_state); + assert_eq!(vec![2], test_state.int); + + test_state.string = vec![vec!['t', 'e', 's', 't', 's']]; + test_state.int = vec![3]; + string_nth(&mut test_state); + assert_eq!(vec!['t'], test_state.char); + + let empty_vec: Vec = vec![]; + test_state.vector_int = vec![empty_vec.clone()]; + test_state.int = vec![10]; + vector_int_nth(&mut test_state); + assert_eq!(vec![empty_vec], test_state.vector_int); + } + + #[test] + fn vector_from_nth_prim_test() { + let mut test_state = EMPTY_STATE; + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5]]; + test_state.int = vec![2]; + vector_int_from_nth_prim(&mut test_state); + assert_eq!(vec![vec![2]], test_state.vector_int); + + let empty_vec = vec![]; + test_state.vector_int = vec![empty_vec.clone()]; + test_state.int = vec![20]; + vector_int_from_nth_prim(&mut test_state); + assert_eq!(vec![empty_vec], test_state.vector_int); + } + + #[test] + fn vector_rest_test() { + let mut test_state = EMPTY_STATE; + let empty_vec: Vec = vec![]; + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5]]; + vector_int_rest(&mut test_state); + assert_eq!(vec![vec![1, 2, 3, 4, 5]], test_state.vector_int); + + test_state.vector_int = vec![vec![0]]; + vector_int_rest(&mut test_state); + assert_eq!(vec![empty_vec.clone()], test_state.vector_int); + + test_state.vector_int = vec![empty_vec.clone()]; + vector_int_rest(&mut test_state); + assert_eq!(vec![empty_vec], test_state.vector_int); + } + + #[test] + fn vector_but_last_test() { + let mut test_state = EMPTY_STATE; + let empty_vec: Vec = vec![]; + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5]]; + vector_int_but_last(&mut test_state); + assert_eq!(vec![vec![0, 1, 2, 3, 4]], test_state.vector_int); + + test_state.vector_int = vec![vec![0]]; + vector_int_but_last(&mut test_state); + assert_eq!(vec![empty_vec.clone()], test_state.vector_int); + + test_state.vector_int = vec![empty_vec.clone()]; + vector_int_but_last(&mut test_state); + assert_eq!(vec![empty_vec], test_state.vector_int); + } + + #[test] + fn vector_drop_test() { + let mut test_state = EMPTY_STATE; + let empty_vec: Vec = vec![]; + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5]]; + test_state.int = vec![2]; + vector_int_drop(&mut test_state); + assert_eq!(vec![vec![2, 3, 4, 5]], test_state.vector_int); + + test_state.vector_int = vec![vec![0]]; + test_state.int = vec![2]; + vector_int_drop(&mut test_state); + assert_eq!(vec![empty_vec.clone()], test_state.vector_int); + + test_state.vector_int = vec![vec![1, 2, 3, 4]]; + test_state.int = vec![4]; + vector_int_drop(&mut test_state); + assert_eq!(vec![empty_vec.clone()], test_state.vector_int); + + test_state.vector_int = vec![empty_vec.clone()]; + test_state.int = vec![30]; + vector_int_drop(&mut test_state); + assert_eq!(vec![empty_vec], test_state.vector_int); + } + + #[test] + fn vector_length_test() { + let mut test_state = EMPTY_STATE; + let empty_vec: Vec = vec![]; + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5]]; + vector_int_length(&mut test_state); + assert_eq!(vec![6], test_state.int); + test_state.int.clear(); + + test_state.vector_int = vec![empty_vec.clone()]; + vector_int_length(&mut test_state); + assert_eq!(vec![0], test_state.int); + test_state.int.clear(); + + test_state.string = vec![vec!['t', 'e', 's']]; + string_length(&mut test_state); + assert_eq!(vec![3], test_state.int); + } + + #[test] + fn vector_reverse() { + let mut test_state = EMPTY_STATE; + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5]]; + vector_int_reverse(&mut test_state); + assert_eq!(vec![vec![5, 4, 3, 2, 1, 0]], test_state.vector_int); } } diff --git a/src/main.rs b/src/main.rs index 53994f4..010d33f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ use instructions::utils::NumericTrait; use rust_decimal::MathematicalOps; use rust_decimal::prelude::*; +use std::collections::VecDeque; mod instructions; mod push; @@ -21,10 +22,10 @@ fn main() { // let result = dec!(1.0) / Decimal::QUARTER_PI.cos(); // let result = dec!(1.2).checked_exp(); // let result = dec!(2).log10(); - let result = vec![0, 1, 2]; + /*let result = vec![0, 1, 2]; let r_len = result.len(); let fin_result = &result[..r_len - 1]; - println!("{fin_result:?}"); + println!("{fin_result:?}");*/ // println!("{result:?}"); // println!("{sixth_pi}"); @@ -33,4 +34,14 @@ fn main() { // test for function equality. // let test_func_result = test_func as usize == test_func as usize; // println!("{test_func_result}"); + + //let temp_vec = vec![0, 1, 2, 3]; + //temp_vec[0..9].to_vec(); + + //let res = 3 % 2; + //println!("res is {res}"); + + let mut test_vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + test_vec.drain(..15); + println!("{:?}", test_vec); }