maitakedayo_rpn_calc/
lib.rs1pub 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 == "" { continue; }
20 match t.parse::<f64>() {
22 Ok(v) => { stack.push(v); continue; },
23 Err(_) => 0.0,
24 };
25 let b = stack.pop().unwrap_or(0.0);
27 let a = stack.pop().unwrap_or(0.0);
28 match t {
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: {}", t)),
35 }
36 }
37 if stack.len() == 0 { return Err(format!("no result")); }
39 if stack.len() > 1 {
40 return Err(format!("too many value in stack"));
41 }
42 Ok(stack.pop().unwrap_or(0.0))
43}
44
45pub fn eval_str(src: &str) -> String {
47 match eval(String::from(src)) {
48 Ok(v) => format!("{}", v),
49 Err(e) => format!("[ERROR] {}", e),
50 }
51}
52
53#[cfg(test)]
55mod tests {
56 use super::*;
57 #[test]
58 fn it_works() {
59 assert_eq!(eval("1 3 +".to_string()), Ok(4.0));
61 assert_eq!(eval("2 3 *".to_string()), Ok(6.0));
62 assert_eq!(eval("6 3 /".to_string()), Ok(2.0));
63 assert_eq!(eval("6 3 - 1 -".to_string()), Ok(2.0));
64 assert_eq!(eval_str("1 2 3 + +"), "6".to_string());
66 assert_eq!(eval_str("1 2 3 * +"), "7".to_string());
67 }
68}
69