More vector instructions
This commit is contained in:
parent
ff078925a1
commit
8748f46fe1
@ -129,7 +129,7 @@ pub mod macros {
|
|||||||
for _ in 0..$fn_arity {
|
for _ in 0..$fn_arity {
|
||||||
state.$in_stack.pop();
|
state.$in_stack.pop();
|
||||||
}
|
}
|
||||||
state.$out_stack.extend(result.iter());
|
state.$out_stack.extend(result.into_iter());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,6 +204,42 @@ pub mod macros {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Same as make_instruction_mult but can handle one auxiliary variable.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! make_instruction_mult_aux {
|
||||||
|
($in_stack:ident, $out_stack:ident, $fn_name:ident, $fn_type:ty, $fn_arity:stmt, $aux_stack:ident, $aux_arity:stmt, $aux_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 aux_stack_len = state.$aux_stack.len();
|
||||||
|
if in_stack_len < $fn_arity || aux_stack_len < $aux_arity {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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..=$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();
|
||||||
|
}
|
||||||
|
state.$out_stack.extend(result.into_iter());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// Same as `make_instruction!` but can work on three stacks. Is there a way
|
/// Same as `make_instruction!` but can work on three stacks. Is there a way
|
||||||
/// to generalize even this?
|
/// to generalize even this?
|
||||||
///
|
///
|
||||||
@ -377,8 +413,11 @@ pub fn string_instructions() -> Vec<fn(&mut PushState)> {
|
|||||||
string_index_of_vector,
|
string_index_of_vector,
|
||||||
string_occurrences_of,
|
string_occurrences_of,
|
||||||
string_occurrences_of_vector,
|
string_occurrences_of_vector,
|
||||||
|
string_parse_to_prim,
|
||||||
string_set_nth,
|
string_set_nth,
|
||||||
|
string_split_on,
|
||||||
string_replace,
|
string_replace,
|
||||||
|
string_remove,
|
||||||
// common.rs
|
// common.rs
|
||||||
string_pop,
|
string_pop,
|
||||||
]
|
]
|
||||||
@ -436,8 +475,11 @@ pub fn vector_int_instructions() -> Vec<fn(&mut PushState)> {
|
|||||||
vector_int_index_of_vector,
|
vector_int_index_of_vector,
|
||||||
vector_int_occurrences_of,
|
vector_int_occurrences_of,
|
||||||
vector_int_occurrences_of_vector,
|
vector_int_occurrences_of_vector,
|
||||||
|
vector_int_parse_to_prim,
|
||||||
vector_int_set_nth,
|
vector_int_set_nth,
|
||||||
|
vector_int_split_on,
|
||||||
vector_int_replace,
|
vector_int_replace,
|
||||||
|
vector_int_remove,
|
||||||
// common.rs
|
// common.rs
|
||||||
vector_int_pop,
|
vector_int_pop,
|
||||||
]
|
]
|
||||||
@ -474,8 +516,11 @@ pub fn vector_float_instructions() -> Vec<fn(&mut PushState)> {
|
|||||||
vector_float_index_of_vector,
|
vector_float_index_of_vector,
|
||||||
vector_float_occurrences_of,
|
vector_float_occurrences_of,
|
||||||
vector_float_occurrences_of_vector,
|
vector_float_occurrences_of_vector,
|
||||||
|
vector_float_parse_to_prim,
|
||||||
vector_float_set_nth,
|
vector_float_set_nth,
|
||||||
|
vector_float_split_on,
|
||||||
vector_float_replace,
|
vector_float_replace,
|
||||||
|
vector_float_remove,
|
||||||
// common.rs
|
// common.rs
|
||||||
vector_float_pop,
|
vector_float_pop,
|
||||||
]
|
]
|
||||||
@ -511,8 +556,11 @@ pub fn vector_string_instructions() -> Vec<fn(&mut PushState)> {
|
|||||||
vector_string_index_of_vector,
|
vector_string_index_of_vector,
|
||||||
vector_string_occurrences_of,
|
vector_string_occurrences_of,
|
||||||
vector_string_occurrences_of_vector,
|
vector_string_occurrences_of_vector,
|
||||||
|
vector_string_parse_to_prim,
|
||||||
vector_string_set_nth,
|
vector_string_set_nth,
|
||||||
|
vector_string_split_on,
|
||||||
vector_string_replace,
|
vector_string_replace,
|
||||||
|
vector_string_remove,
|
||||||
// common.rs
|
// common.rs
|
||||||
vector_string_pop,
|
vector_string_pop,
|
||||||
]
|
]
|
||||||
@ -549,8 +597,11 @@ pub fn vector_boolean_instructions() -> Vec<fn(&mut PushState)> {
|
|||||||
vector_boolean_index_of_vector,
|
vector_boolean_index_of_vector,
|
||||||
vector_boolean_occurrences_of,
|
vector_boolean_occurrences_of,
|
||||||
vector_boolean_occurrences_of_vector,
|
vector_boolean_occurrences_of_vector,
|
||||||
|
vector_boolean_parse_to_prim,
|
||||||
vector_boolean_set_nth,
|
vector_boolean_set_nth,
|
||||||
|
vector_boolean_split_on,
|
||||||
vector_boolean_replace,
|
vector_boolean_replace,
|
||||||
|
vector_boolean_remove,
|
||||||
// common.rs
|
// common.rs
|
||||||
vector_boolean_pop,
|
vector_boolean_pop,
|
||||||
]
|
]
|
||||||
@ -587,8 +638,11 @@ pub fn vector_char_instructions() -> Vec<fn(&mut PushState)> {
|
|||||||
vector_char_index_of_vector,
|
vector_char_index_of_vector,
|
||||||
vector_char_occurrences_of,
|
vector_char_occurrences_of,
|
||||||
vector_char_occurrences_of_vector,
|
vector_char_occurrences_of_vector,
|
||||||
|
vector_char_parse_to_prim,
|
||||||
vector_char_set_nth,
|
vector_char_set_nth,
|
||||||
|
vector_char_split_on,
|
||||||
vector_char_replace,
|
vector_char_replace,
|
||||||
|
vector_char_remove,
|
||||||
// common.rs
|
// common.rs
|
||||||
vector_char_pop,
|
vector_char_pop,
|
||||||
]
|
]
|
||||||
|
@ -980,9 +980,10 @@ make_instruction_aux!(
|
|||||||
);
|
);
|
||||||
make_instruction_aux!(string, int, _occurrences_of, Vec<char>, 1, char, 1, char);
|
make_instruction_aux!(string, int, _occurrences_of, Vec<char>, 1, char, 1, char);
|
||||||
|
|
||||||
|
/// Counts the amount of continuous occurrences one vector appears in another.
|
||||||
pub fn _occurrences_of_vector<T>(vals: Vec<Vec<T>>) -> Option<i128>
|
pub fn _occurrences_of_vector<T>(vals: Vec<Vec<T>>) -> Option<i128>
|
||||||
where
|
where
|
||||||
T: Eq + Hash,
|
T: Eq,
|
||||||
{
|
{
|
||||||
if vals[0].is_empty() {
|
if vals[0].is_empty() {
|
||||||
return Some(0);
|
return Some(0);
|
||||||
@ -1007,13 +1008,27 @@ make_instruction_clone!(vector_boolean, int, _occurrences_of_vector, Vec<bool>,
|
|||||||
make_instruction_clone!(vector_char, int, _occurrences_of_vector, Vec<char>, 2);
|
make_instruction_clone!(vector_char, int, _occurrences_of_vector, Vec<char>, 2);
|
||||||
make_instruction_clone!(string, int, _occurrences_of_vector, Vec<char>, 2);
|
make_instruction_clone!(string, int, _occurrences_of_vector, Vec<char>, 2);
|
||||||
|
|
||||||
/// Pushes the values inside a vector to a primitive stack.
|
/// Pushes the values inside a vector separated into individual vectors back to
|
||||||
pub fn _parse_to_prim<T>(vals: Vec<Vec<T>>) -> Option<Vec<T>>
|
/// the stack.
|
||||||
|
pub fn _parse_to_prim<T>(vals: Vec<Vec<T>>) -> Option<Vec<Vec<T>>>
|
||||||
where
|
where
|
||||||
T: Clone,
|
T: Clone,
|
||||||
|
Vec<T>: FromIterator<T>,
|
||||||
{
|
{
|
||||||
Some(vals[0].clone())
|
Some(vals[0].clone().into_iter().map(|x| vec![x]).collect())
|
||||||
}
|
}
|
||||||
|
make_instruction_mult!(vector_int, vector_int, _parse_to_prim, Vec<i128>, 1);
|
||||||
|
make_instruction_mult!(vector_float, vector_float, _parse_to_prim, Vec<Decimal>, 1);
|
||||||
|
make_instruction_mult!(
|
||||||
|
vector_string,
|
||||||
|
vector_string,
|
||||||
|
_parse_to_prim,
|
||||||
|
Vec<Vec<char>>,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
make_instruction_mult!(vector_boolean, vector_boolean, _parse_to_prim, Vec<bool>, 1);
|
||||||
|
make_instruction_mult!(vector_char, vector_char, _parse_to_prim, Vec<char>, 1);
|
||||||
|
make_instruction_mult!(string, string, _parse_to_prim, Vec<char>, 1);
|
||||||
|
|
||||||
/// Sets the nth index in a vector. N from the int stack.
|
/// Sets the nth index in a vector. N from the int stack.
|
||||||
pub fn _set_nth<T>(vals: Vec<Vec<T>>, aux0: Vec<T>, aux1: Vec<i128>) -> Option<Vec<T>>
|
pub fn _set_nth<T>(vals: Vec<Vec<T>>, aux0: Vec<T>, aux1: Vec<i128>) -> Option<Vec<T>>
|
||||||
@ -1104,8 +1119,129 @@ make_instruction_aux2!(
|
|||||||
i128
|
i128
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Replaces all values in a vector with respect to two ints. The first int is the search value
|
/// Splits a vector based the first occurence of a primitive
|
||||||
/// and the second value is the one to replace.
|
pub fn _split_on<T>(vals: Vec<Vec<T>>, auxs: Vec<T>) -> Option<Vec<Vec<T>>>
|
||||||
|
where
|
||||||
|
T: Clone + Eq,
|
||||||
|
Vec<T>: FromIterator<T>,
|
||||||
|
{
|
||||||
|
let mut final_vec = vec![];
|
||||||
|
let mut temp_vec = vec![];
|
||||||
|
for val in vals[0].iter() {
|
||||||
|
if &auxs[0] == val {
|
||||||
|
final_vec.push(temp_vec.clone());
|
||||||
|
temp_vec.clear();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
temp_vec.push(val.clone());
|
||||||
|
}
|
||||||
|
if !temp_vec.is_empty() {
|
||||||
|
final_vec.push(temp_vec);
|
||||||
|
}
|
||||||
|
Some(final_vec)
|
||||||
|
}
|
||||||
|
make_instruction_mult_aux!(
|
||||||
|
vector_int,
|
||||||
|
vector_int,
|
||||||
|
_split_on,
|
||||||
|
Vec<i128>,
|
||||||
|
1,
|
||||||
|
int,
|
||||||
|
1,
|
||||||
|
i128
|
||||||
|
);
|
||||||
|
make_instruction_mult_aux!(
|
||||||
|
vector_float,
|
||||||
|
vector_float,
|
||||||
|
_split_on,
|
||||||
|
Vec<Decimal>,
|
||||||
|
1,
|
||||||
|
float,
|
||||||
|
1,
|
||||||
|
Decimal
|
||||||
|
);
|
||||||
|
make_instruction_mult_aux!(
|
||||||
|
vector_string,
|
||||||
|
vector_string,
|
||||||
|
_split_on,
|
||||||
|
Vec<Vec<char>>,
|
||||||
|
1,
|
||||||
|
string,
|
||||||
|
1,
|
||||||
|
Vec<char>
|
||||||
|
);
|
||||||
|
make_instruction_mult_aux!(
|
||||||
|
vector_boolean,
|
||||||
|
vector_boolean,
|
||||||
|
_split_on,
|
||||||
|
Vec<bool>,
|
||||||
|
1,
|
||||||
|
boolean,
|
||||||
|
1,
|
||||||
|
bool
|
||||||
|
);
|
||||||
|
make_instruction_mult_aux!(
|
||||||
|
vector_char,
|
||||||
|
vector_char,
|
||||||
|
_split_on,
|
||||||
|
Vec<char>,
|
||||||
|
1,
|
||||||
|
char,
|
||||||
|
1,
|
||||||
|
char
|
||||||
|
);
|
||||||
|
make_instruction_mult_aux!(string, string, _split_on, Vec<char>, 1, char, 1, char);
|
||||||
|
|
||||||
|
/*/// Splits a vector based the first occurence of a primitive
|
||||||
|
pub fn _split_on_vector<T>(vals: Vec<Vec<T>>) -> Option<Vec<Vec<T>>>
|
||||||
|
where
|
||||||
|
T: Clone + Eq,
|
||||||
|
{
|
||||||
|
if vals[0].is_empty() {
|
||||||
|
return Some(vec![vals[1]]);
|
||||||
|
}
|
||||||
|
let mut final_vec = vec![];
|
||||||
|
let mut temp_vec = vec![];
|
||||||
|
for val in vals[1].windows(vals[0].len()) {
|
||||||
|
if &auxs[0] == val {
|
||||||
|
final_vec.push(temp_vec.clone());
|
||||||
|
temp_vec.clear();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
temp_vec.push(val.clone());
|
||||||
|
}
|
||||||
|
if !temp_vec.is_empty() {
|
||||||
|
final_vec.push(temp_vec);
|
||||||
|
}
|
||||||
|
Some(final_vec)
|
||||||
|
}
|
||||||
|
make_instruction_mult!(vector_int, vector_int, _split_on_vector, Vec<i128>, 1);
|
||||||
|
make_instruction_mult!(
|
||||||
|
vector_float,
|
||||||
|
vector_float,
|
||||||
|
_split_on_vector,
|
||||||
|
Vec<Decimal>,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
make_instruction_mult!(
|
||||||
|
vector_string,
|
||||||
|
vector_string,
|
||||||
|
_split_on_vector,
|
||||||
|
Vec<Vec<char>>,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
make_instruction_mult!(
|
||||||
|
vector_boolean,
|
||||||
|
vector_boolean,
|
||||||
|
_split_on_vector,
|
||||||
|
Vec<bool>,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
make_instruction_mult!(vector_char, vector_char, _split_on_vector, Vec<char>, 1);
|
||||||
|
make_instruction_mult!(string, string, _split_on_vector, Vec<char>, 1);*/
|
||||||
|
|
||||||
|
/// Replaces all values in a vector with respect to two primitives. The first primitive is
|
||||||
|
/// the search value and the second value is the one to replace.
|
||||||
pub fn _replace<T>(mut vals: Vec<Vec<T>>, auxs: Vec<T>) -> Option<Vec<T>>
|
pub fn _replace<T>(mut vals: Vec<Vec<T>>, auxs: Vec<T>) -> Option<Vec<T>>
|
||||||
where
|
where
|
||||||
T: Clone,
|
T: Clone,
|
||||||
@ -1168,6 +1304,64 @@ make_instruction_aux!(
|
|||||||
);
|
);
|
||||||
make_instruction_aux!(string, string, _replace, Vec<char>, 1, char, 2, char);
|
make_instruction_aux!(string, string, _replace, Vec<char>, 1, char, 2, char);
|
||||||
|
|
||||||
|
/// Removes all values in a vector with respect to a primitives. If is equal, remove it.
|
||||||
|
pub fn _remove<T>(vals: Vec<Vec<T>>, auxs: Vec<T>) -> Option<Vec<T>>
|
||||||
|
where
|
||||||
|
T: Clone,
|
||||||
|
for<'a> &'a T: Eq,
|
||||||
|
Vec<T>: FromIterator<T>,
|
||||||
|
{
|
||||||
|
let temp_vec = &vals[0];
|
||||||
|
let ret_vec = temp_vec
|
||||||
|
.iter()
|
||||||
|
.filter(|&x| x != &auxs[0])
|
||||||
|
.cloned()
|
||||||
|
.collect();
|
||||||
|
Some(ret_vec)
|
||||||
|
}
|
||||||
|
make_instruction_aux!(vector_int, vector_int, _remove, Vec<i128>, 1, int, 1, i128);
|
||||||
|
make_instruction_aux!(
|
||||||
|
vector_float,
|
||||||
|
vector_float,
|
||||||
|
_remove,
|
||||||
|
Vec<Decimal>,
|
||||||
|
1,
|
||||||
|
float,
|
||||||
|
1,
|
||||||
|
Decimal
|
||||||
|
);
|
||||||
|
make_instruction_aux!(
|
||||||
|
vector_string,
|
||||||
|
vector_string,
|
||||||
|
_remove,
|
||||||
|
Vec<Vec<char>>,
|
||||||
|
1,
|
||||||
|
string,
|
||||||
|
1,
|
||||||
|
Vec<char>
|
||||||
|
);
|
||||||
|
make_instruction_aux!(
|
||||||
|
vector_boolean,
|
||||||
|
vector_boolean,
|
||||||
|
_remove,
|
||||||
|
Vec<bool>,
|
||||||
|
1,
|
||||||
|
boolean,
|
||||||
|
1,
|
||||||
|
bool
|
||||||
|
);
|
||||||
|
make_instruction_aux!(
|
||||||
|
vector_char,
|
||||||
|
vector_char,
|
||||||
|
_remove,
|
||||||
|
Vec<char>,
|
||||||
|
1,
|
||||||
|
char,
|
||||||
|
1,
|
||||||
|
char
|
||||||
|
);
|
||||||
|
make_instruction_aux!(string, string, _remove, Vec<char>, 1, char, 1, char);
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -1732,6 +1926,45 @@ mod tests {
|
|||||||
assert_eq!(vec![vec![true, false, true]], test_state.vector_boolean);
|
assert_eq!(vec![vec![true, false, true]], test_state.vector_boolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_to_prim_test() {
|
||||||
|
let mut test_state = EMPTY_STATE;
|
||||||
|
|
||||||
|
test_state.vector_int = vec![vec![0, 1, 2]];
|
||||||
|
vector_int_parse_to_prim(&mut test_state);
|
||||||
|
assert_eq!(vec![vec![0], vec![1], vec![2]], test_state.vector_int);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn split_on_test() {
|
||||||
|
let mut test_state = EMPTY_STATE;
|
||||||
|
|
||||||
|
test_state.vector_int = vec![vec![0, 1, 2]];
|
||||||
|
test_state.int = vec![1];
|
||||||
|
vector_int_split_on(&mut test_state);
|
||||||
|
assert_eq!(vec![vec![0], vec![2]], test_state.vector_int);
|
||||||
|
|
||||||
|
test_state.vector_int = vec![vec![0, 1, 2, 1, 5]];
|
||||||
|
test_state.int = vec![1];
|
||||||
|
vector_int_split_on(&mut test_state);
|
||||||
|
assert_eq!(vec![vec![0], vec![2], vec![5]], test_state.vector_int);
|
||||||
|
|
||||||
|
test_state.vector_int = vec![vec![0, 1, 2, 1]];
|
||||||
|
test_state.int = vec![1];
|
||||||
|
vector_int_split_on(&mut test_state);
|
||||||
|
assert_eq!(vec![vec![0], vec![2]], test_state.vector_int);
|
||||||
|
|
||||||
|
test_state.vector_int = vec![vec![0, 1, 2, 1]];
|
||||||
|
test_state.int = vec![9];
|
||||||
|
vector_int_split_on(&mut test_state);
|
||||||
|
assert_eq!(vec![vec![0, 1, 2, 1]], test_state.vector_int);
|
||||||
|
|
||||||
|
test_state.vector_int = vec![vec![0, 1, 2, 3]];
|
||||||
|
test_state.int = vec![3];
|
||||||
|
vector_int_split_on(&mut test_state);
|
||||||
|
assert_eq!(vec![vec![0, 1, 2]], test_state.vector_int);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn replace_test() {
|
fn replace_test() {
|
||||||
let mut test_state = EMPTY_STATE;
|
let mut test_state = EMPTY_STATE;
|
||||||
@ -1741,4 +1974,24 @@ mod tests {
|
|||||||
vector_int_replace(&mut test_state);
|
vector_int_replace(&mut test_state);
|
||||||
assert_eq!(vec![vec![0, 1, 3, 3, 4, 5, 3]], test_state.vector_int);
|
assert_eq!(vec![vec![0, 1, 3, 3, 4, 5, 3]], test_state.vector_int);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn remove_test() {
|
||||||
|
let mut test_state = EMPTY_STATE;
|
||||||
|
|
||||||
|
test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5, 2]];
|
||||||
|
test_state.int = vec![3];
|
||||||
|
vector_int_remove(&mut test_state);
|
||||||
|
assert_eq!(vec![vec![0, 1, 2, 4, 5, 2]], test_state.vector_int);
|
||||||
|
|
||||||
|
test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5, 2]];
|
||||||
|
test_state.int = vec![2];
|
||||||
|
vector_int_remove(&mut test_state);
|
||||||
|
assert_eq!(vec![vec![0, 1, 3, 4, 5]], test_state.vector_int);
|
||||||
|
|
||||||
|
test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5, 2]];
|
||||||
|
test_state.int = vec![9];
|
||||||
|
vector_int_remove(&mut test_state);
|
||||||
|
assert_eq!(vec![vec![0, 1, 2, 3, 4, 5, 2]], test_state.vector_int);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user