11 // structure to hold an expression in the stack
16 // function to compute a result by popping the stack and
17 // pushing back the result
18 fn get_result (t : &mut Vec<Expression>, op : Operator) -> Result<f32,String> {
19 // pop the stack for last operand
20 // if nothing - panic with error
23 return Err ("Illegal expression".to_string());
25 // pop the stack for the first operand
26 // if nothing - panic with error
29 return Err ("Illegal expression!".to_string());
32 let num1 = n1.unwrap().value;
33 let num2 = n2.unwrap().value;
35 // depending on the operation, set the result
38 t.push (Expression{value: num2 + num1});
42 t.push (Expression{value: num2 - num1});
46 t.push (Expression{value: num2 * num1});
50 t.push (Expression{value: num2 / num1});
56 // evaluation function
57 fn evaluate (expr : &str, match_num : ®ex::Regex) -> Result<f32,String> {
58 let mut ops = Vec::<Expression>::new ();
59 // tokenize the individual words by splitting at whitespace
60 let words = expr.split_whitespace ();
62 // iterate over the words
65 // if the word matches one of +, -, *, / then push it on the stack
66 // and immediately evaluate the expression by popping the operator
67 // and the last two operands and push the result back on to the stack
69 let m = get_result (&mut ops, Operator::ADD);
71 return Err (m.unwrap_err().to_string());
75 let m = get_result (&mut ops, Operator::SUB);
77 return Err (m.unwrap_err().to_string());
81 let m = get_result (&mut ops, Operator::MUL);
83 return Err (m.unwrap_err().to_string());
87 let m = get_result (&mut ops, Operator::DIV);
89 return Err (m.unwrap_err().to_string());
92 // if word matches a number, push it on to the stack
93 _ => if match_num.is_match (word) {
94 let num = word.parse ().unwrap ();
95 ops.push (Expression { value: num });
97 // if word doesn't match either operator or number then panic.
99 return Err ("Error parsing expression! \
100 Must be a number or operator (+,-,* or /)".to_string());
106 // if the stack has more than one value, it means that the postfix
107 // expression is not complete - so display the stack status
108 return Err ("Postfix expression incomplete!".to_string());
110 // stack has only one item which is the result so display it
111 let res = ops[0].value;
117 // get a line from input and evaluate it
118 let mut expr = String::new ();
119 // regular expression to match a number
120 let match_num = Regex::new (r"^\d+?.*?\d*?$").unwrap ();
121 // loop until a blank line is received
124 println!("Enter an expression (postfix) (blank to quit): ");
125 // read a line of text
126 io::stdin().read_line (&mut expr).expect ("Error reading line!");
128 let expr = expr.trim ();
129 // quit if the expression is blank
134 let res = evaluate (&expr, &match_num);
136 println! ("Result is : {}", res.unwrap());
139 eprintln! ("Error: {}", res.unwrap_err());