improve comparisons

This commit is contained in:
Pyther99 2021-07-13 19:32:26 +02:00 committed by finngaertner2@gmx.de
parent 3ee5e00b11
commit beb1ea7506
3 changed files with 29 additions and 35 deletions

View File

@ -12,27 +12,19 @@ use crate::FunctionIdentifier::{Cbrt, Ceil, Cos, Exp, Abs, Floor, Ln, Log, Round
use crate::units::Unit; use crate::units::Unit;
use crate::units::Unit::*; use crate::units::Unit::*;
use unicode_segmentation::{Graphemes, UnicodeSegmentation}; use unicode_segmentation::{Graphemes, UnicodeSegmentation};
use std::cmp::Ordering;
fn is_word_char_str(input: &str) -> bool { fn is_word_char_str(input: &str) -> bool {
let x = match input { matches!(input, "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L"
"A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L"
| "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X"
| "Y" | "Z" => true, | "Y" | "Z" | "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l"
"a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l"
| "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x"
| "y" | "z" => true, | "y" | "z" | "Ω" | "" | "µ" | "μ")
"Ω" | "" | "µ" | "μ" => true,
_ => false,
};
return x;
} }
fn is_numeric_str(input: &str) -> bool { fn is_numeric_str(input: &str) -> bool {
match input { matches!(input, "." | "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9")
"." => true,
"0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" => true,
_ => false,
}
} }
/// Read next characters as a word, otherwise return empty string. /// Read next characters as a word, otherwise return empty string.
@ -54,7 +46,7 @@ fn read_word_plain(chars: &mut Peekable<Graphemes>) -> String {
fn read_word(first_c: &str, lexer: &mut Lexer) -> String { fn read_word(first_c: &str, lexer: &mut Lexer) -> String {
let chars = &mut lexer.chars; let chars = &mut lexer.chars;
let mut word = first_c.trim().to_owned(); let mut word = first_c.trim().to_owned();
if word == "" { if word.is_empty() {
// skip whitespace // skip whitespace
while let Some(current_char) = chars.peek() { while let Some(current_char) = chars.peek() {
if current_char.trim().is_empty() { if current_char.trim().is_empty() {
@ -71,7 +63,7 @@ fn read_word(first_c: &str, lexer: &mut Lexer) -> String {
break; break;
} }
} }
if word != "" { if !word.is_empty() {
match *chars.peek().unwrap_or(&"") { match *chars.peek().unwrap_or(&"") {
"2" | "²" => { "2" | "²" => {
word += "2"; word += "2";
@ -633,15 +625,19 @@ pub fn lex(input: &str, remove_trailing_operator: bool, default_degree: Unit) ->
} }
let tokens = &mut lexer.tokens; let tokens = &mut lexer.tokens;
// auto insert missing parentheses in first and last position // auto insert missing parentheses in first and last position
if lexer.left_paren_count > lexer.right_paren_count { match lexer.left_paren_count.cmp(&lexer.right_paren_count) {
Ordering::Less => {
let missing_left_parens = lexer.right_paren_count - lexer.left_paren_count;
for _ in 0..missing_left_parens {
tokens.insert(0, Token::Operator(LeftParen));
}
}
Ordering::Equal => {}
Ordering::Greater => {
let missing_right_parens = lexer.left_paren_count - lexer.right_paren_count; let missing_right_parens = lexer.left_paren_count - lexer.right_paren_count;
for _ in 0..missing_right_parens { for _ in 0..missing_right_parens {
tokens.push(Token::Operator(RightParen)); tokens.push(Token::Operator(RightParen));
} }
} else if lexer.left_paren_count < lexer.right_paren_count {
let missing_left_parens = lexer.right_paren_count - lexer.left_paren_count;
for _ in 0..missing_left_parens {
tokens.insert(0, Token::Operator(LeftParen));
} }
} }

View File

@ -232,20 +232,20 @@ pub fn eval(input: &str, allow_trailing_operators: bool, default_degree: Unit, v
match lexer::lex(input, allow_trailing_operators, default_degree) { match lexer::lex(input, allow_trailing_operators, default_degree) {
Ok(tokens) => { Ok(tokens) => {
let lex_time = Instant::now().duration_since(lex_start).as_nanos() as f32; let lex_time = Instant::now().duration_since(lex_start).as_nanos() as f32;
if verbose == true { println!("Lexed TokenVector: {:?}", tokens); } if verbose { println!("Lexed TokenVector: {:?}", tokens); }
let parse_start = Instant::now(); let parse_start = Instant::now();
match parser::parse(&tokens) { match parser::parse(&tokens) {
Ok(ast) => { Ok(ast) => {
let parse_time = Instant::now().duration_since(parse_start).as_nanos() as f32; let parse_time = Instant::now().duration_since(parse_start).as_nanos() as f32;
if verbose == true { println!("Parsed AstNode: {:#?}", ast); } if verbose { println!("Parsed AstNode: {:#?}", ast); }
let eval_start = Instant::now(); let eval_start = Instant::now();
match evaluator::evaluate(&ast) { match evaluator::evaluate(&ast) {
Ok(answer) => { Ok(answer) => {
let eval_time = Instant::now().duration_since(eval_start).as_nanos() as f32; let eval_time = Instant::now().duration_since(eval_start).as_nanos() as f32;
if verbose == true { if verbose {
println!("Evaluated value: {} {:?}", answer.value, answer.unit); println!("Evaluated value: {} {:?}", answer.value, answer.unit);
println!("\u{23f1} {:.3}ms lexing", lex_time/1000.0/1000.0); println!("\u{23f1} {:.3}ms lexing", lex_time/1000.0/1000.0);
println!("\u{23f1} {:.3}ms parsing", parse_time/1000.0/1000.0); println!("\u{23f1} {:.3}ms parsing", parse_time/1000.0/1000.0);

View File

@ -544,16 +544,14 @@ fn actual_multiply(left: Number, right: Number, swapped: bool) -> Result<Number,
// 1 watt * 1 second = 1 joule // 1 watt * 1 second = 1 joule
let result = (left.value * left.unit.weight()) * (right.value * right.unit.weight() / Unit::Second.weight()); let result = (left.value * left.unit.weight()) * (right.value * right.unit.weight() / Unit::Second.weight());
match right.unit { match right.unit {
Second => return Ok(to_ideal_joule_unit(Number::new(result, Joule))), Second => Ok(to_ideal_joule_unit(Number::new(result, Joule))),
_ => return Ok(to_ideal_unit(Number::new(result, Joule))), _ => Ok(to_ideal_unit(Number::new(result, Joule))),
}; }
} else { } else if swapped {
if swapped == true {
Err(format!("Cannot multiply {:?} and {:?}", right.unit, left.unit)) Err(format!("Cannot multiply {:?} and {:?}", right.unit, left.unit))
} else { } else {
actual_multiply(right, left, true) actual_multiply(right, left, true)
} }
}
} }
/// Divide a [`Number`] by another [`Number`] /// Divide a [`Number`] by another [`Number`]