1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use core::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UnaryOp {
Neg, Pos, Inv, Not,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BinaryOp {
Mul, Div, Mod,
Add, Sub,
LShift, RShift,
BitAnd,
BitXor,
BitOr,
LT, GT, LE, GE,
EQ, NE,
And,
Or,
}
pub type Precedence = u8;
pub const PRECEDENCE_END: Precedence = 0;
pub const PRECEDENCE_START: Precedence = 10;
impl BinaryOp {
pub const fn precedence_level(&self) -> Precedence {
match self {
BinaryOp::Mul | BinaryOp::Div | BinaryOp::Mod => 1,
BinaryOp::Add | BinaryOp::Sub => 2,
BinaryOp::LShift | BinaryOp::RShift => 3,
BinaryOp::BitAnd => 4,
BinaryOp::BitXor => 5,
BinaryOp::BitOr => 6,
BinaryOp::LT | BinaryOp::GT | BinaryOp::LE | BinaryOp::GE => 7,
BinaryOp::EQ | BinaryOp::NE => 8,
BinaryOp::And => 9,
BinaryOp::Or => 10,
}
}
}
impl fmt::Display for BinaryOp {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let symbol = match self {
BinaryOp::Mul => "*",
BinaryOp::Div => "/",
BinaryOp::Mod => "%",
BinaryOp::Add => "+",
BinaryOp::Sub => "-",
BinaryOp::LShift => "<<",
BinaryOp::RShift => ">>",
BinaryOp::BitAnd => "&",
BinaryOp::BitXor => "^",
BinaryOp::BitOr => "|",
BinaryOp::LT => "<",
BinaryOp::GT => ">",
BinaryOp::LE => "<=",
BinaryOp::GE => ">=",
BinaryOp::EQ => "==",
BinaryOp::NE => "!=",
BinaryOp::And => "and",
BinaryOp::Or => "or",
};
fmt.write_str(symbol)
}
}