improve comparisons
This commit is contained in:
parent
3ee5e00b11
commit
beb1ea7506
38
src/lexer.rs
38
src/lexer.rs
@ -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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
10
src/units.rs
10
src/units.rs
@ -544,17 +544,15 @@ 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`]
|
||||||
///
|
///
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user