From 017450ce7ec0961c0862b3b67dcd3f41ab4a302c Mon Sep 17 00:00:00 2001 From: Vegard Matthey Date: Sun, 7 Apr 2024 22:56:45 +0200 Subject: [PATCH] fix (n) - (n) and (n) - n --- Cargo.toml | 7 ++++++- release.sh | 5 +++++ src/main.rs | 46 ++++++++++++++++++++++++++++++++++++---------- 3 files changed, 47 insertions(+), 11 deletions(-) create mode 100755 release.sh diff --git a/Cargo.toml b/Cargo.toml index e145edd..69899b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,11 @@ name = "calc" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[profile.release] +strip = true +opt-level = "z" +lto = true +codegen-units = 1 +panic = "abort" [dependencies] diff --git a/release.sh b/release.sh new file mode 100755 index 0000000..ea5f55f --- /dev/null +++ b/release.sh @@ -0,0 +1,5 @@ +#!/bin/sh +RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build -Z build-std=std,panic_abort -Z build-std-features=panic_immediate_abort \ + --target x86_64-unknown-linux-gnu --release +upx --best --lzma target/x86_64-unknown-linux-gnu/release/calc +cp target/x86_64-unknown-linux-gnu/release/calc calc diff --git a/src/main.rs b/src/main.rs index 4cfe003..31dffc0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -68,8 +68,18 @@ fn main() { } } +impl Token { + fn is_operator(&self) -> bool { + use Token::*; + match self { + Multiply | Divide | Add | Subtract | Modulus | Power => true, + LeftParenthesis | RightParenthesis | Separator | Number(_) | Function(_) => false, + } + } +} + fn print_result(result: f64) { - if result > 1000. || (result < 0.001 && result > -0.001) && result != 0. { + if result > 10_000. || (result < 0.0001 && result > -0.0001) && result != 0. { println!("{:e}", result); } else { println!("{result}"); @@ -91,7 +101,9 @@ fn compute(input: &str) -> f64 { } }; + println!("tokens before: {:?}", tokens); let tokens = implicit_operations(tokens); + println!("tokens after: {:?}", tokens); let tokens = infix_to_postfix(tokens); match calculate(tokens) { @@ -274,15 +286,23 @@ fn implicit_operations(tokens: Vec) -> Vec { match a { Token::Number(_) => new_tokens.push(c.clone()), _ => { - if b == &Token::Subtract { + if *b == Token::Subtract { if let Token::Number(n) = c { - new_tokens.pop(); - new_tokens.push(Token::Number(-n)); - } else if c == &Token::LeftParenthesis { - new_tokens.pop(); - new_tokens.push(Token::Number(-1.)); - new_tokens.push(Token::Multiply); - new_tokens.push(Token::LeftParenthesis); + if a.is_operator() { + new_tokens.pop(); + new_tokens.push(Token::Number(-n)); + } else { + new_tokens.push(c.clone()); + } + } else if *c == Token::LeftParenthesis { + if *a == Token::LeftParenthesis { + new_tokens.pop(); + new_tokens.push(Token::Number(-1.)); + new_tokens.push(Token::Multiply); + new_tokens.push(Token::LeftParenthesis); + } else { + new_tokens.push(c.clone()); + } } } else { new_tokens.push(c.clone()); @@ -371,7 +391,11 @@ fn calculate(tokens: Vec) -> Result { let mut token = tokens.next().unwrap(); while let Token::Number(_) = token { stack.push(token.clone()); - token = tokens.next().unwrap(); + if let Some(t) = tokens.next() { + token = t; + } else { + break; + } } let a = stack.pop().ok_or(CalculateError::PostfixExpectedNumbers)?; @@ -703,5 +727,7 @@ mod tests { assert_eq!(compute("3 -+ 2"), 1.); assert_eq!(compute("1E-3"), 0.001); assert_eq!(compute("3sin(3)"), 3. * 3_f64.sin()); + assert_eq!(compute("(1 + 2) - (1)"), 2.); + assert_eq!(compute("(1 + 2) - 1"), 2.); } }