better hints
This commit is contained in:
parent
b7c734205d
commit
72943f5e2f
14
Cargo.lock
generated
14
Cargo.lock
generated
@ -1374,15 +1374,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.23.1"
|
||||
version = "0.24.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6"
|
||||
checksum = "8f17df307904acd05aa8e32e97bb20f2a0df1728bbc2d771ae8f9a90463441e9"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cc",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"memoffset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1746,9 +1744,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pprof"
|
||||
version = "0.8.0"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2324292407eab69d4ace0eed1524fe612ac37c98aa22b0d868355b17fada530"
|
||||
checksum = "6f9307de92566887d485ac6f20df17b0fe1704fffdbad0bdbc05a3864d3082f6"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"cfg-if 1.0.0",
|
||||
@ -1756,7 +1754,7 @@ dependencies = [
|
||||
"inferno",
|
||||
"libc",
|
||||
"log",
|
||||
"nix 0.23.1",
|
||||
"nix 0.24.1",
|
||||
"once_cell",
|
||||
"parking_lot 0.12.0",
|
||||
"smallvec",
|
||||
@ -1939,7 +1937,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruzstd"
|
||||
version = "0.2.4"
|
||||
source = "git+https://github.com/Titaniumtown/zstd-rs.git?branch=ringbuffer#b89410c7a25135e9caff80df2a82d322debd2644"
|
||||
source = "git+https://github.com/Titaniumtown/zstd-rs.git?branch=ringbuffer#56972fa1fe8b188ad2f1f54fe1fe35d9479a2d9f"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"twox-hash",
|
||||
|
||||
@ -7,7 +7,7 @@ license = "AGPL-3.0"
|
||||
[lib]
|
||||
|
||||
[dependencies]
|
||||
pprof = { version = "0.8", features = ["flamegraph"] }
|
||||
pprof = { version = "0.9", features = ["flamegraph"] }
|
||||
criterion = "0.3"
|
||||
criterion-macro = "0.3"
|
||||
parsing = { path = "../parsing" }
|
||||
|
||||
@ -11,7 +11,7 @@ fn compare_len_reverse_alpha(a: &String, b: &String) -> Ordering {
|
||||
|
||||
/// Generates hashmap (well really a vector of tuple of strings that are then turned into a hashmap by phf)
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn compile_hashmap(data: Vec<String>) -> Vec<(String, String)> {
|
||||
fn compile_hashmap(data: Vec<String>) -> Vec<(String, String)> {
|
||||
let mut seen = HashSet::new();
|
||||
|
||||
let tuple_list_1: Vec<(String, String)> = data
|
||||
|
||||
@ -22,13 +22,20 @@ pub fn split_function(input: &str) -> Vec<String> {
|
||||
.replace("exp", "\u{1fc93}") // stop-gap solution to fix the `exp` function
|
||||
.chars()
|
||||
.collect::<Vec<char>>(),
|
||||
SplitType::Multiplication,
|
||||
)
|
||||
.iter()
|
||||
.map(|x| x.replace("\u{1fc93}", "exp")) // Convert back to `exp` text
|
||||
.collect::<Vec<String>>()
|
||||
}
|
||||
|
||||
pub fn split_function_chars(chars: &[char]) -> Vec<String> {
|
||||
#[derive(PartialEq)]
|
||||
pub enum SplitType {
|
||||
Multiplication,
|
||||
Term,
|
||||
}
|
||||
|
||||
pub fn split_function_chars(chars: &[char], split: SplitType) -> Vec<String> {
|
||||
if chars.is_empty() {
|
||||
return Vec::new();
|
||||
}
|
||||
@ -52,6 +59,7 @@ pub fn split_function_chars(chars: &[char]) -> Vec<String> {
|
||||
/// Used to store info about a character
|
||||
struct BoolSlice {
|
||||
closing_parens: bool,
|
||||
open_parens: bool,
|
||||
number: bool,
|
||||
letter: bool,
|
||||
variable: bool,
|
||||
@ -65,6 +73,7 @@ pub fn split_function_chars(chars: &[char]) -> Vec<String> {
|
||||
let isvariable = is_variable(c);
|
||||
Self {
|
||||
closing_parens: *c == ')',
|
||||
open_parens: *c == '(',
|
||||
number: isnumber,
|
||||
letter: c.is_ascii_alphabetic(),
|
||||
variable: isvariable,
|
||||
@ -101,8 +110,8 @@ pub fn split_function_chars(chars: &[char]) -> Vec<String> {
|
||||
}
|
||||
}
|
||||
|
||||
const fn splitable(&self, c: &char, other: &BoolSlice) -> bool {
|
||||
if *c == '*' {
|
||||
fn splitable(&self, c: &char, other: &BoolSlice, split: &SplitType) -> bool {
|
||||
if (c == &'*') | ((split == &SplitType::Term) && other.open_parens) {
|
||||
return true;
|
||||
} else if other.closing_parens {
|
||||
// Cases like `)x`, `)2`, and `)(`
|
||||
@ -147,13 +156,13 @@ pub fn split_function_chars(chars: &[char]) -> Vec<String> {
|
||||
curr_c.calculate_mask(&prev_char);
|
||||
|
||||
// Append split
|
||||
if curr_c.splitable(c, &prev_char) {
|
||||
if curr_c.splitable(c, &prev_char, &split) {
|
||||
data.push(String::new());
|
||||
last = unsafe { data.last_mut().unwrap_unchecked() };
|
||||
}
|
||||
|
||||
// Exclude asterisks
|
||||
if *c != '*' {
|
||||
if c != &'*' {
|
||||
last.push(*c);
|
||||
}
|
||||
|
||||
@ -168,29 +177,42 @@ pub fn split_function_chars(chars: &[char]) -> Vec<String> {
|
||||
pub fn generate_hint<'a>(input: &str) -> &'a Hint<'a> {
|
||||
if input.is_empty() {
|
||||
return &HINT_EMPTY;
|
||||
}
|
||||
} else {
|
||||
let chars: Vec<char> = input.chars().collect::<Vec<char>>();
|
||||
|
||||
let chars: Vec<char> = input.chars().collect::<Vec<char>>();
|
||||
unsafe {
|
||||
assume(!chars.is_empty());
|
||||
}
|
||||
|
||||
if let Some(hint) = COMPLETION_HASHMAP.get(get_last_term(&chars).as_str()) {
|
||||
return hint;
|
||||
}
|
||||
|
||||
let mut open_parens: usize = 0;
|
||||
let mut closed_parens: usize = 0;
|
||||
chars.iter().for_each(|chr| match *chr {
|
||||
'(' => open_parens += 1,
|
||||
')' => closed_parens += 1,
|
||||
_ => {}
|
||||
});
|
||||
|
||||
if open_parens > closed_parens {
|
||||
return &HINT_CLOSED_PARENS;
|
||||
}
|
||||
|
||||
return &Hint::None;
|
||||
}
|
||||
}
|
||||
|
||||
fn get_last_term(chars: &[char]) -> String {
|
||||
assert!(!chars.is_empty());
|
||||
|
||||
unsafe {
|
||||
assume(!chars.is_empty());
|
||||
split_function_chars(chars, SplitType::Term)
|
||||
.last()
|
||||
.unwrap_unchecked()
|
||||
.to_owned()
|
||||
}
|
||||
|
||||
let mut open_parens: usize = 0;
|
||||
let mut closed_parens: usize = 0;
|
||||
chars.iter().for_each(|chr| match *chr {
|
||||
'(' => open_parens += 1,
|
||||
')' => closed_parens += 1,
|
||||
_ => {}
|
||||
});
|
||||
|
||||
if open_parens > closed_parens {
|
||||
return &HINT_CLOSED_PARENS;
|
||||
}
|
||||
|
||||
COMPLETION_HASHMAP
|
||||
.get(&unsafe { split_function_chars(&chars).last().unwrap_unchecked() }.as_str())
|
||||
.unwrap_or(&Hint::None)
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
@ -253,6 +275,7 @@ mod tests {
|
||||
("ln(x)", Hint::None),
|
||||
("ln(x)cos", Hint::Many(&["(", "h("])),
|
||||
("ln(x)*cos", Hint::Many(&["(", "h("])),
|
||||
("sin(cos", Hint::Many(&["(", "h("])),
|
||||
]);
|
||||
|
||||
for (key, value) in values {
|
||||
@ -350,4 +373,25 @@ mod tests {
|
||||
assert!(!hint.is_single());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_last_term() {
|
||||
let values = HashMap::from([
|
||||
("cos(x)", "x)"),
|
||||
("cos(", "cos("),
|
||||
("aaaaaaaaaaa", "aaaaaaaaaaa"),
|
||||
("x", "x"),
|
||||
("xxx", "x"),
|
||||
("x*x", "x"),
|
||||
("10*10", "10"),
|
||||
("sin(cos", "cos"),
|
||||
]);
|
||||
|
||||
for (key, value) in values {
|
||||
assert_eq!(
|
||||
super::get_last_term(key.chars().collect::<Vec<char>>().as_slice()),
|
||||
value
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user