Skip to content

Instantly share code, notes, and snippets.

@Titaniumtown
Created November 25, 2023 17:23
Show Gist options
  • Save Titaniumtown/c181be5d06505e003d8c4d1e372684ff to your computer and use it in GitHub Desktop.
Save Titaniumtown/c181be5d06505e003d8c4d1e372684ff to your computer and use it in GitHub Desktop.
add_asterisks public domain
I hereby release the following code with the CC0/public domain license:
/*
EXTREMELY Janky function that tries to put asterisks in the proper places to be parsed. This is so cursed. But it works, and I hopefully won't ever have to touch it again.
One limitation though, variables with multiple characters like `pi` cannot be multiplied (like `pipipipi` won't result in `pi*pi*pi*pi`). But that's such a niche use case (and that same thing could be done by using exponents) that it doesn't really matter.
In the future I may want to completely rewrite this or implement this natively into mevel-rs (which would probably be good to do)
*/
pub fn add_asterisks(function_in: String) -> String {
let function = function_in.replace("log10(", "log(").replace("pi", "π"); // pi -> π and log10 -> log
let valid_variables: Vec<char> = "xeπ".chars().collect();
let letters: Vec<char> = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
.chars()
.collect();
let numbers: Vec<char> = "0123456789".chars().collect();
let function_chars: Vec<char> = function.chars().collect();
let mut output_string: String = String::new();
let mut prev_chars: Vec<char> = Vec::new();
for c in function_chars {
let mut add_asterisk: bool = false;
let prev_chars_len = prev_chars.len();
let prev_prev_char = if prev_chars_len >= 2 {
*prev_chars.get(prev_chars_len - 2).unwrap()
} else {
' '
};
let prev_char = if prev_chars_len >= 1 {
*prev_chars.get(prev_chars_len - 1).unwrap()
} else {
' '
};
let c_letters_var = letters.contains(&c) | valid_variables.contains(&c);
let prev_letters_var = valid_variables.contains(&prev_char) | letters.contains(&prev_char);
if prev_char == ')' {
if (c == '(') | numbers.contains(&c) | c_letters_var {
add_asterisk = true;
}
} else if c == '(' {
if (valid_variables.contains(&prev_char)
| (')' == prev_char)
| numbers.contains(&prev_char))
&& !letters.contains(&prev_prev_char)
{
add_asterisk = true;
}
} else if numbers.contains(&prev_char) {
if (c == '(') | c_letters_var {
add_asterisk = true;
}
} else if letters.contains(&c) {
if numbers.contains(&prev_char)
| (valid_variables.contains(&prev_char) && valid_variables.contains(&c))
{
add_asterisk = true;
}
} else if (numbers.contains(&c) | c_letters_var) && prev_letters_var {
add_asterisk = true;
}
if add_asterisk {
output_string += "*";
}
prev_chars.push(c);
output_string += &c.to_string();
}
output_string.replace('π', "pi") // π -> pi
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment