xxx_rpn_calc/
lib.rs

1//
2/// Eval RPN
3/// # Example
4/// ```
5/// let src = String::from("1 2 + 3 *");
6/// let a = rpn_calc::eval(src).unwrap();
7/// println!("{}", a);
8/// ```
9pub fn eval(src:String) -> Result<f64, String> {
10    let mut stack:Vec<f64> = vec![];
11
12    let tokens = src.split_whitespace();
13
14    for tok in tokens {
15        let t = tok.trim();
16        match t.parse::<f64>() {
17            Ok(v) => { stack.push(v); continue;},
18            Err(_) => 0.0,
19        };
20
21        let b = stack.pop().unwrap();
22        let a = stack.pop().unwrap();
23        match t {
24            "+" => stack.push(a + b),
25            "-" => stack.push(a - b),
26            "*" => stack.push(a * b),
27            "/" => stack.push(a / b),
28            _ => panic!("未定義の演算子:{}", t)
29        };
30    }
31
32    if stack.len() == 0 {
33        return Err(format!("no result"));
34    }
35    if stack.len() > 1 {
36        return Err(format!("too many value in stack"));
37    }
38    Ok(stack.pop().unwrap_or(0.0))
39}
40
41
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46
47    #[test]
48    fn it_works() {
49        assert_eq!(eval("1 3 +".to_string()), Ok(4.0));
50        assert_eq!(eval("2 3 *".to_string()), Ok(6.0));
51    }
52}