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