use super::{BinaryOp, ExprKind, Expression, UnaryOp};
pub(crate) fn precedence(op: BinaryOp) -> u8 {
match op {
BinaryOp::Add | BinaryOp::Sub | BinaryOp::PlusMinus | BinaryOp::MinusPlus => 1,
BinaryOp::Mul | BinaryOp::Div | BinaryOp::Mod => 2,
BinaryOp::Pow => 3,
}
}
pub(crate) fn needs_parens(child: &Expression, parent_op: BinaryOp, is_right: bool) -> bool {
match &child.kind {
ExprKind::Binary { op: child_op, .. } => {
let parent_prec = precedence(parent_op);
let child_prec = precedence(*child_op);
if child_prec < parent_prec {
return true;
}
if child_prec == parent_prec {
match (parent_op, *child_op) {
(BinaryOp::Pow, BinaryOp::Pow) => return true,
(BinaryOp::Sub, BinaryOp::Sub) | (BinaryOp::Div, BinaryOp::Div) => {
return is_right
}
_ => {}
}
}
false
}
ExprKind::Unary { op, .. } => {
matches!(
(parent_op, op, is_right),
(BinaryOp::Pow, UnaryOp::Neg | UnaryOp::Pos, false)
)
}
_ => false,
}
}