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