updated
This commit is contained in:
@@ -10,13 +10,13 @@ description = "Parsing library for YTBN-Graphing-Software"
|
||||
[lib]
|
||||
|
||||
[dependencies]
|
||||
phf = { version = "0.10", no-default-features = true }
|
||||
phf = { version = "0.11", no-default-features = true }
|
||||
exmex = { git = "https://github.com/bertiqwerty/exmex.git", branch = "main", features = [
|
||||
"partial",
|
||||
] }
|
||||
|
||||
[build-dependencies]
|
||||
phf_codegen = { version = "0.10", no-default-features = true }
|
||||
phf_codegen = { version = "0.11", no-default-features = true }
|
||||
|
||||
[package.metadata.cargo-all-features]
|
||||
skip_optional_dependencies = true #don't test optional dependencies, only features
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn compile_hashmap(data: Vec<String>) -> Vec<(String, String)> {
|
||||
let mut seen_3: HashSet<String> = HashSet::new();
|
||||
|
||||
for (key, value) in tuple_list_1.iter() {
|
||||
if seen_3.contains(&*key) {
|
||||
if seen_3.contains(key) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -33,18 +33,20 @@ pub fn compile_hashmap(data: Vec<String>) -> Vec<(String, String)> {
|
||||
|
||||
let count_keys = keys.iter().filter(|a| a == &&key).count();
|
||||
|
||||
if count_keys == 1 {
|
||||
output.push((key.clone(), format!(r#"Hint::Single("{}")"#, value)));
|
||||
} else if count_keys > 1 {
|
||||
let mut multi_data = tuple_list_1
|
||||
.iter()
|
||||
.filter(|(a, _)| a == key)
|
||||
.map(|(_, b)| b)
|
||||
.collect::<Vec<&String>>();
|
||||
multi_data.sort_unstable_by(|a, b| compare_len_reverse_alpha(a, b));
|
||||
output.push((key.clone(), format!("Hint::Many(&{:?})", multi_data)));
|
||||
} else {
|
||||
panic!("Number of values for {key} is 0!");
|
||||
match count_keys.cmp(&1usize) {
|
||||
Ordering::Less => {
|
||||
panic!("Number of values for {key} is 0!");
|
||||
}
|
||||
Ordering::Greater => {
|
||||
let mut multi_data = tuple_list_1
|
||||
.iter()
|
||||
.filter(|(a, _)| a == key)
|
||||
.map(|(_, b)| b)
|
||||
.collect::<Vec<&String>>();
|
||||
multi_data.sort_unstable_by(|a, b| compare_len_reverse_alpha(a, b));
|
||||
output.push((key.clone(), format!("Hint::Many(&{:?})", multi_data)));
|
||||
}
|
||||
Ordering::Equal => output.push((key.clone(), format!(r#"Hint::Single("{}")"#, value))),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,12 +26,7 @@ impl FlatExWrapper {
|
||||
fn partial(&self, x: usize) -> Self {
|
||||
self.func
|
||||
.as_ref()
|
||||
.map(|f| {
|
||||
f.clone()
|
||||
.partial(x)
|
||||
.map(|a| Self::new(a))
|
||||
.unwrap_or(Self::EMPTY)
|
||||
})
|
||||
.map(|f| f.clone().partial(x).map(Self::new).unwrap_or(Self::EMPTY))
|
||||
.unwrap_or(Self::EMPTY)
|
||||
}
|
||||
|
||||
@@ -44,8 +39,8 @@ impl FlatExWrapper {
|
||||
.as_ref()
|
||||
.map(|f| {
|
||||
f.clone()
|
||||
.partial_iter((0..=n).map(|_| 0).into_iter())
|
||||
.map(|a| Self::new(a))
|
||||
.partial_iter((0..=n).map(|_| 0))
|
||||
.map(Self::new)
|
||||
.unwrap_or(Self::EMPTY)
|
||||
})
|
||||
.unwrap_or(Self::EMPTY)
|
||||
@@ -151,8 +146,7 @@ impl BackingFunction {
|
||||
|
||||
/// Get string relating to the nth derivative
|
||||
pub fn get_nth_derivative_str(&self) -> &str {
|
||||
&self
|
||||
.nth_derivative
|
||||
self.nth_derivative
|
||||
.as_ref()
|
||||
.map(|a| a.2.as_str())
|
||||
.unwrap_or("")
|
||||
@@ -207,6 +201,6 @@ pub fn process_func_str(function_in: &str) -> String {
|
||||
return String::new();
|
||||
}
|
||||
|
||||
crate::suggestions::split_function(&function_in, crate::suggestions::SplitType::Multiplication)
|
||||
crate::suggestions::split_function(function_in, crate::suggestions::SplitType::Multiplication)
|
||||
.join("*")
|
||||
}
|
||||
|
||||
@@ -25,11 +25,11 @@ pub fn split_function(input: &str, split: SplitType) -> Vec<String> {
|
||||
split,
|
||||
)
|
||||
.iter()
|
||||
.map(|x| x.replace("\u{1fc93}", "exp")) // Convert back to `exp` text
|
||||
.map(|x| x.replace('\u{1fc93}', "exp")) // Convert back to `exp` text
|
||||
.collect::<Vec<String>>()
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub enum SplitType {
|
||||
Multiplication,
|
||||
Term,
|
||||
@@ -108,7 +108,7 @@ pub fn split_function_chars(chars: &[char], split: SplitType) -> Vec<String> {
|
||||
|
||||
const fn splitable(&self, c: &char, other: &BoolSlice, split: &SplitType) -> bool {
|
||||
if (*c == '*') | (matches!(split, &SplitType::Term) && other.open_parens) {
|
||||
return true;
|
||||
true
|
||||
} else if other.closing_parens {
|
||||
// Cases like `)x`, `)2`, and `)(`
|
||||
return (*c == '(')
|
||||
@@ -131,11 +131,8 @@ pub fn split_function_chars(chars: &[char], split: SplitType) -> Vec<String> {
|
||||
&& (other.is_unmasked_number() | other.letter)
|
||||
{
|
||||
return true;
|
||||
} else if self.is_unmasked_number() && other.is_unmasked_variable() {
|
||||
// Cases like `x2`
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
return self.is_unmasked_number() && other.is_unmasked_variable();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -173,7 +170,7 @@ pub fn split_function_chars(chars: &[char], split: SplitType) -> Vec<String> {
|
||||
/// Generate a hint based on the input `input`, returns an `Option<String>`
|
||||
pub fn generate_hint<'a>(input: &str) -> &'a Hint<'a> {
|
||||
if input.is_empty() {
|
||||
return &HINT_EMPTY;
|
||||
&HINT_EMPTY
|
||||
} else {
|
||||
let chars: Vec<char> = input.chars().collect::<Vec<char>>();
|
||||
|
||||
@@ -181,8 +178,16 @@ pub fn generate_hint<'a>(input: &str) -> &'a Hint<'a> {
|
||||
assume(!chars.is_empty());
|
||||
}
|
||||
|
||||
if let Some(hint) = COMPLETION_HASHMAP.get(get_last_term(&chars).as_str()) {
|
||||
return hint;
|
||||
let key = get_last_term(&chars);
|
||||
match key {
|
||||
Some(key) => {
|
||||
if let Some(hint) = COMPLETION_HASHMAP.get(&key) {
|
||||
return hint;
|
||||
}
|
||||
}
|
||||
None => {
|
||||
return &Hint::None;
|
||||
}
|
||||
}
|
||||
|
||||
let mut open_parens: usize = 0;
|
||||
@@ -197,21 +202,17 @@ pub fn generate_hint<'a>(input: &str) -> &'a Hint<'a> {
|
||||
return &HINT_CLOSED_PARENS;
|
||||
}
|
||||
|
||||
return &Hint::None;
|
||||
&Hint::None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_last_term(chars: &[char]) -> String {
|
||||
assert!(!chars.is_empty());
|
||||
pub fn get_last_term(chars: &[char]) -> Option<String> {
|
||||
if chars.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut result = split_function_chars(chars, SplitType::Term);
|
||||
unsafe {
|
||||
assume(!result.is_empty());
|
||||
assume(result.len() > 0);
|
||||
let output = result.pop();
|
||||
assume(output.is_some());
|
||||
output.unwrap_unchecked()
|
||||
}
|
||||
result.pop()
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Copy)]
|
||||
@@ -225,13 +226,13 @@ impl<'a> std::fmt::Display for Hint<'a> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Hint::Single(single_data) => {
|
||||
return write!(f, "{}", single_data);
|
||||
write!(f, "{}", single_data)
|
||||
}
|
||||
Hint::Many(multi_data) => {
|
||||
return write!(f, "{:?}", multi_data);
|
||||
write!(f, "{:?}", multi_data)
|
||||
}
|
||||
Hint::None => {
|
||||
return write!(f, "None");
|
||||
write!(f, "None")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -277,3 +278,33 @@ impl<'a> Hint<'a> {
|
||||
}
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
|
||||
|
||||
#[cfg(test)]
|
||||
fn assert_test(input: &str, expected: &[&str], split: SplitType) {
|
||||
let output = split_function("sin(x)cos(x)", SplitType::Multiplication);
|
||||
let expected_owned = expected
|
||||
.iter()
|
||||
.map(|&x| x.to_owned())
|
||||
.collect::<Vec<String>>();
|
||||
if output != expected_owned {
|
||||
panic!(
|
||||
"split type: {:?} of {} resulted in {:?} not {:?}",
|
||||
split, input, output, expected
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn split_function_test() {
|
||||
assert_test(
|
||||
"sin(x)cos(x)",
|
||||
&["sin(x)", "cos(x)"],
|
||||
SplitType::Multiplication,
|
||||
);
|
||||
|
||||
assert_test(
|
||||
"tanh(cos(x)xx)cos(x)",
|
||||
&["tanh(cos(x)", "x", "x)", "cos(x)"],
|
||||
SplitType::Multiplication,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user