mathew/reflect/
operator.rs

1use std::cmp::Ordering;
2
3#[derive(Debug, Clone, Copy, PartialEq)]
4#[repr(u8)]
5pub(super) enum Operator {
6    ParenLeft = 1 << 2,
7    ParenRight = (1 << 2) + 1,
8    Fn = (1 << 2) + 2,
9
10    Neg = 1 << 3,
11
12    Mul = 1 << 4,
13    Div = (1 << 4) + 1,
14    Rem = (1 << 4) + 2,
15
16    Add = 1 << 5,
17    Sub = (1 << 5) + 1,
18}
19
20impl Operator {
21    fn preference(&self, o: &Operator) -> Ordering {
22        (*self as u8)
23            .leading_zeros()
24            .cmp(&(*o as u8).leading_zeros())
25    }
26
27    pub(super) fn ge_preference(&self, o: &Operator) -> bool {
28        match self.preference(o) {
29            Ordering::Greater | Ordering::Equal => true,
30            _ => false,
31        }
32    }
33
34    pub(super) fn eq_preference(&self, o: &Operator) -> bool {
35        match self.preference(o) {
36            Ordering::Equal => true,
37            _ => false,
38        }
39    }
40}
41
42#[cfg(test)]
43mod test {
44    use super::*;
45
46    #[test]
47    fn test_op_preference() {
48        assert!(Operator::Add.ge_preference(&Operator::Sub) && Operator::Sub != Operator::Add);
49        assert!(Operator::Neg.ge_preference(&Operator::Neg) && Operator::Neg == Operator::Neg);
50        assert!(!Operator::Add.ge_preference(&Operator::Neg));
51        assert!(Operator::Neg.ge_preference(&Operator::Add));
52    }
53}