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