Pops operands from the `expr` stack, applies this operation, and pushes the result back.
(&self, exprs: &mut Vec<Expr>)
| 203 | |
| 204 | /// Pops operands from the `expr` stack, applies this operation, and pushes the result back. |
| 205 | fn apply(&self, exprs: &mut Vec<Expr>) -> Result<()> { |
| 206 | fn apply1( |
| 207 | exprs: &mut Vec<Expr>, |
| 208 | pos: LineCol, |
| 209 | f: fn(Box<UnaryOpSpan>) -> Expr, |
| 210 | ) -> Result<()> { |
| 211 | if exprs.is_empty() { |
| 212 | return Err(Error::Bad(pos, "Not enough values to apply operator".to_owned())); |
| 213 | } |
| 214 | let expr = exprs.pop().unwrap(); |
| 215 | exprs.push(f(Box::from(UnaryOpSpan { expr, pos }))); |
| 216 | Ok(()) |
| 217 | } |
| 218 | |
| 219 | fn apply2( |
| 220 | exprs: &mut Vec<Expr>, |
| 221 | pos: LineCol, |
| 222 | f: fn(Box<BinaryOpSpan>) -> Expr, |
| 223 | ) -> Result<()> { |
| 224 | if exprs.len() < 2 { |
| 225 | return Err(Error::Bad(pos, "Not enough values to apply operator".to_owned())); |
| 226 | } |
| 227 | let rhs = exprs.pop().unwrap(); |
| 228 | let lhs = exprs.pop().unwrap(); |
| 229 | exprs.push(f(Box::from(BinaryOpSpan { lhs, rhs, pos }))); |
| 230 | Ok(()) |
| 231 | } |
| 232 | |
| 233 | match self.op { |
| 234 | ExprOp::Add => apply2(exprs, self.pos, Expr::Add), |
| 235 | ExprOp::Subtract => apply2(exprs, self.pos, Expr::Subtract), |
| 236 | ExprOp::Multiply => apply2(exprs, self.pos, Expr::Multiply), |
| 237 | ExprOp::Divide => apply2(exprs, self.pos, Expr::Divide), |
| 238 | ExprOp::Modulo => apply2(exprs, self.pos, Expr::Modulo), |
| 239 | ExprOp::Power => apply2(exprs, self.pos, Expr::Power), |
| 240 | |
| 241 | ExprOp::Equal => apply2(exprs, self.pos, Expr::Equal), |
| 242 | ExprOp::NotEqual => apply2(exprs, self.pos, Expr::NotEqual), |
| 243 | ExprOp::Less => apply2(exprs, self.pos, Expr::Less), |
| 244 | ExprOp::LessEqual => apply2(exprs, self.pos, Expr::LessEqual), |
| 245 | ExprOp::Greater => apply2(exprs, self.pos, Expr::Greater), |
| 246 | ExprOp::GreaterEqual => apply2(exprs, self.pos, Expr::GreaterEqual), |
| 247 | |
| 248 | ExprOp::And => apply2(exprs, self.pos, Expr::And), |
| 249 | ExprOp::Or => apply2(exprs, self.pos, Expr::Or), |
| 250 | ExprOp::Xor => apply2(exprs, self.pos, Expr::Xor), |
| 251 | |
| 252 | ExprOp::ShiftLeft => apply2(exprs, self.pos, Expr::ShiftLeft), |
| 253 | ExprOp::ShiftRight => apply2(exprs, self.pos, Expr::ShiftRight), |
| 254 | |
| 255 | ExprOp::Negate => apply1(exprs, self.pos, Expr::Negate), |
| 256 | ExprOp::Not => apply1(exprs, self.pos, Expr::Not), |
| 257 | |
| 258 | ExprOp::LeftParen => Ok(()), |
| 259 | } |
| 260 | } |
| 261 | } |
| 262 |