rpn_reckoner/lib.rs
1//! # RPN-Reckoner
2//! Reverse Polish Notation (: RPN) - Reckoner
3//! # Example1
4//! ```
5//! let expression = String::from("1 2 +");
6//! let solution = rpn_reckoner::eval(expression).unwrap();
7//! println!("{}", solution); // -> 3
8//! ```
9//! # Example2
10//! ```
11//! let expression = String::from("5 2 - 3 +");
12//! let solution = rpn_reckoner::eval(expression).unwrap();
13//! println!("{}", solution); // -> 6
14//! ```
15//! # Example3
16//! ```
17//! let expression = String::from("5 2 3 ^ +");
18//! let solution = rpn_reckoner::eval(expression).unwrap();
19//! println!("{}", solution); // -> 13
20//! ```
21//! # Example4
22//! ```
23//! let expression = String::from("4 ! 2 +");
24//! let solution = rpn_reckoner::eval(expression).unwrap();
25//! println!("{}", solution); // -> 26
26//! ```
27
28mod operation;
29
30
31/// The function computes RPN expressions
32pub fn eval(expression: String) -> Result<f64, String> {
33 // Separate tokens with white space
34 let tokens = expression.split_whitespace();
35
36 let mut stack: Vec<f64> = Vec::new();
37 for token in tokens {
38 let t = token.trim();
39 if t == "" { continue; }
40
41 // Push values onto the stack
42 match t.parse::<f64>() {
43 Ok(value) => { stack.push(value); continue; },
44 Err(_) => 0.0,
45 };
46
47 // Push calculation results onto the stack
48 let right = stack.pop().unwrap_or(0.0);
49 let left = stack.pop().unwrap_or(0.0);
50 match t {
51 // Operator
52 "+" => stack.push(left + right),
53 "-" => stack.push(left - right),
54 "*" => stack.push(left * right),
55 "/" => stack.push(left / right),
56 "%" => stack.push(left % right),
57
58 // Power
59 "^" => stack.push(left.powf(right)),
60 "**" => stack.push(left.powf(right)),
61
62 // Factorial
63 "!" => {
64 if left != 0.0 { stack.push(left); }
65 stack.push(operation::factorial(right)); },
66
67 // Error
68 _ => return Err(format!("[Error] Invalid operator: {}", t)),
69 }
70 }
71
72 if stack.len() == 0 { return Err(format!("[Error] No result.")); }
73 if stack.len() > 1 { return Err(format!("[Error] Too many values in the stack.")); }
74
75 Ok(stack.pop().unwrap_or(0.0))
76}
77
78
79mod test;