1
2pub fn calc(src: String) -> Result<f64, String> {
3
4 let tokens = src.split_whitespace();
5 let mut stack: Vec<f64> = vec![];
6
7 for v in tokens {
8
9 let trim = v.trim();
10
11 if trim == "" {
12 continue;
13 }
14
15 match trim.parse::<f64>() {
16
17 Ok(v2) => {
18 stack.push(v2);
19 continue;
20 },
21 Err(_) => 0.0,
22
23 };
24
25 let b = stack.pop().unwrap_or(0.0);
26 let a = stack.pop().unwrap_or(0.0);
27
28 match trim {
29 "+" => stack.push(a + b),
30 "-" => stack.push(a - b),
31 "*" => stack.push(a * b),
32 "/" => stack.push(a / b),
33 "%" => stack.push(a % b),
34 _ => return Err(format!("invalid operator {}", trim)),
35 };
36
37
38 }
39
40 if stack.len() == 0 {
41 return Err(format!("no result"));
42 }
43
44 if stack.len() > 1 {
45 return Err(format!("too many value in stack"));
46 }
47
48 Ok(stack.pop().unwrap_or(0.0))
49
50}
51
52
53#[cfg(test)]
54mod tests {
55
56 use super::*;
57
58 #[test]
59 fn it_works() {
60
61 assert_eq!(calc("2 3 +".to_string()), Ok(5.0));
62 assert_eq!(calc("2 3 *".to_string()), Ok(6.0));
63 assert_eq!(calc("6 3 /".to_string()), Ok(2.0));
64 assert_eq!(calc("6 3 - 1 -".to_string()), Ok(2.0));
65
66 }
67
68}
69
70
71
72
73
74
75
76
77
78
79
80
81
82