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