kengos_test_rpn_calc/
lib.rs1pub fn eval(src: String) -> Result<f64, String> {
9 let tokens = src.split_whitespace();
10 let mut stack: Vec<f64> = vec![];
11 for token in tokens {
12 let t = token.trim();
13 match t.parse::<f64>() {
14 Ok(v) => {
15 stack.push(v);
16 continue;
17 }
18 Err(_) => 0.0,
19 };
20 let b = stack.pop().unwrap();
21 let a = stack.pop().unwrap();
22 match t {
23 "+" => stack.push(a + b),
24 "-" => stack.push(a - b),
25 "*" => stack.push(a * b),
26 "/" => stack.push(a / b),
27 _ => return Err(format!("invalid operator: {}", t)),
28 };
29 }
30
31 if stack.len() == 0 {
32 return Err(format!("no result"));
33 }
34 if stack.len() > 1 {
35 return Err(format!("too many value in stack"));
36 }
37 Ok(stack.pop().unwrap_or(0.0))
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43
44 #[test]
45 fn it_works() {
46 assert_eq!(eval("1 3 +".to_string()), Ok(4.0));
47 assert_eq!(eval("2.22 4.2 -".to_string()), Ok(-1.98));
48 assert_eq!(eval("2 3 *".to_string()), Ok(6.0));
49 assert_eq!(eval("6 3 /".to_string()), Ok(2.0));
50 assert_eq!(eval("6 3 - 1 -".to_string()), Ok(2.0));
51 assert_eq!(
52 eval("6 6".to_string()),
53 Err("too many value in stack".to_string())
54 );
55 assert_eq!(
56 eval("6 6 + 3 !".to_string()),
57 Err("invalid operator: !".to_string())
58 );
59 assert_eq!(eval("".to_string()), Err("no result".to_string()));
60 }
61}