rpn_example/
lib.rs

1
2pub fn calc(src: String) -> Result<f64, String> {
3
4    let tokens = src.split_whitespace();
5    let mut stack: Vec<f64> = vec![];
6
7    for v in tokens {
8
9        let trim = v.trim();
10
11        if trim == "" {
12            continue;
13        }
14
15        match trim.parse::<f64>() {
16
17            Ok(v2) => {
18                stack.push(v2);
19                continue;
20            },
21            Err(_) => 0.0,
22
23        };
24
25        let b = stack.pop().unwrap_or(0.0);
26        let a = stack.pop().unwrap_or(0.0);
27
28        match trim {
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 {}", trim)),
35        };
36
37
38    }
39
40    if stack.len() == 0 { 
41        return Err(format!("no result"));
42    }
43
44    if stack.len() > 1 { 
45        return Err(format!("too many value in stack"));
46    }
47
48    Ok(stack.pop().unwrap_or(0.0))
49
50}
51
52
53#[cfg(test)]
54mod tests {
55
56    use super::*;
57
58    #[test]
59    fn it_works() {
60
61        assert_eq!(calc("2 3 +".to_string()), Ok(5.0));
62        assert_eq!(calc("2 3 *".to_string()), Ok(6.0));
63        assert_eq!(calc("6 3 /".to_string()), Ok(2.0));
64        assert_eq!(calc("6 3 - 1 -".to_string()), Ok(2.0));
65
66    }
67
68}
69
70
71
72
73
74
75
76
77
78
79
80
81
82