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