From fb2a1645074e9b65de9561e435d43546dabb1dd6 Mon Sep 17 00:00:00 2001 From: emma Date: Fri, 2 Feb 2024 15:35:36 -0700 Subject: [PATCH] rpn(1): rewrote parser for the second time --- src/rpn.rs | 83 ++++++++++++++++++++++-------------------------------- 1 file changed, 33 insertions(+), 50 deletions(-) diff --git a/src/rpn.rs b/src/rpn.rs index 0f39187..7cba297 100644 --- a/src/rpn.rs +++ b/src/rpn.rs @@ -67,7 +67,7 @@ enum CalcType { Floor, Modulo, Val(f64), - Empty, + Invalid, } impl From<&str> for CalcType { @@ -83,7 +83,7 @@ impl From<&str> for CalcType { _ => { match value.parse::() { Ok(x) => Val(x), - Err(_) => Empty, + Err(_) => Invalid, } }, } @@ -104,7 +104,7 @@ impl Display for CalcType { Val(x) => { y = x.to_string(); &y }, - Empty => "", + Invalid => "", }) } } @@ -122,6 +122,7 @@ impl Display for EvaluationError { // repeating and it seems this can give it to me const PRECISION_MOD: f64 = 0.9 + f64::EPSILON * 100.0; + fn eval( input: &str, initial_stack: VecDeque, @@ -135,64 +136,45 @@ fn eval( } // Split the input into tokens. - let toks = input.split(' ').collect::>(); + let mut toks: VecDeque = input + .split(' ') + .map(|t| CalcType::from(t)) + .collect(); let mut ops: VecDeque = VecDeque::new(); - for tok in toks { - let x: CalcType = match CalcType::from(tok) { - Empty => { + while let Some(n) = toks.pop_back() { + match n { + Val(v) => stack.push_back(v), + Invalid => { return Err(EvaluationError { - message: format!("{}: Invalid token", tok), + message: format!("{}: Invalid token", n) }) }, - x => x, - }; + op => { + ops.push_back(op); + oper = true; - match x { - Val(v) => stack.push_back(v), - _ => ops.push_back(x), - } - } + let vals = ( + stack.pop_back(), + stack.pop_back(), + ); - for op in &ops { - match op { - Val(_) => { - return Err(EvaluationError { message: format!( - "{}: Unexpected value in the operator stack.", - op, - )}); - }, - _ => { - - if stack.len() < 2 { + if let (Some(x), Some(y)) = vals { + match op { + Add => stack.push_back(y + x), + Subtract => stack.push_back(y - x), + Multiply => stack.push_back(y * x), + Divide => stack.push_back(y / x), + Power => stack.push_back(x.powf(y)), + Floor => stack.push_back((y / x).floor()), + Modulo => stack.push_back(y % x), + _ => {}, + }; + } else { return Err(EvaluationError { message: format!("{}: Unexpected operation.", op) }) } - - if stack.len() > ops.len() + 1 { - return Err( - EvaluationError { message: format!("Syntax error.")} - ); - } - - oper = true; - - let (x, y) = ( - stack.pop_back().unwrap(), - stack.pop_back().unwrap(), - ); - - match op { - Add => stack.push_back(y + x), - Subtract => stack.push_back(y - x), - Multiply => stack.push_back(y * x), - Divide => stack.push_back(y / x), - Power => stack.push_back(x.powf(y)), - Floor => stack.push_back((y / x).floor()), - Modulo => stack.push_back(y % x), - _ => {}, - }; }, }; } @@ -240,6 +222,7 @@ fn main() -> ExitCode { let input = argv .iter() .skip(1) + .rev() .map(|x| x.to_owned()) .collect::>() .join(" ");