syntax/ast/
operators.rs

1//! Defines a bunch of data-less enums for unary and binary operators.
2//!
3//! Types here don't know about AST, this allows re-using them for both AST and
4//! HIR.
5use std::fmt;
6
7#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
8pub enum RangeOp {
9    /// `..`
10    Exclusive,
11    /// `..=`
12    Inclusive,
13}
14
15#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
16pub enum UnaryOp {
17    /// `*`
18    Deref,
19    /// `!`
20    Not,
21    /// `-`
22    Neg,
23}
24
25#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
26pub enum BinaryOp {
27    LogicOp(LogicOp),
28    ArithOp(ArithOp),
29    CmpOp(CmpOp),
30    Assignment { op: Option<ArithOp> },
31}
32
33#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
34pub enum LogicOp {
35    And,
36    Or,
37}
38
39#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
40pub enum CmpOp {
41    Eq { negated: bool },
42    Ord { ordering: Ordering, strict: bool },
43}
44
45#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
46pub enum Ordering {
47    Less,
48    Greater,
49}
50
51#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
52pub enum ArithOp {
53    Add,
54    Mul,
55    Sub,
56    Div,
57    Rem,
58    Shl,
59    Shr,
60    BitXor,
61    BitOr,
62    BitAnd,
63}
64
65impl fmt::Display for LogicOp {
66    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67        let res = match self {
68            LogicOp::And => "&&",
69            LogicOp::Or => "||",
70        };
71        f.write_str(res)
72    }
73}
74
75impl fmt::Display for ArithOp {
76    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77        let res = match self {
78            ArithOp::Add => "+",
79            ArithOp::Mul => "*",
80            ArithOp::Sub => "-",
81            ArithOp::Div => "/",
82            ArithOp::Rem => "%",
83            ArithOp::Shl => "<<",
84            ArithOp::Shr => ">>",
85            ArithOp::BitXor => "^",
86            ArithOp::BitOr => "|",
87            ArithOp::BitAnd => "&",
88        };
89        f.write_str(res)
90    }
91}
92
93impl fmt::Display for CmpOp {
94    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95        let res = match self {
96            CmpOp::Eq { negated: false } => "==",
97            CmpOp::Eq { negated: true } => "!=",
98            CmpOp::Ord { ordering: Ordering::Less, strict: false } => "<=",
99            CmpOp::Ord { ordering: Ordering::Less, strict: true } => "<",
100            CmpOp::Ord { ordering: Ordering::Greater, strict: false } => ">=",
101            CmpOp::Ord { ordering: Ordering::Greater, strict: true } => ">",
102        };
103        f.write_str(res)
104    }
105}
106
107impl fmt::Display for BinaryOp {
108    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109        match self {
110            BinaryOp::LogicOp(op) => fmt::Display::fmt(op, f),
111            BinaryOp::ArithOp(op) => fmt::Display::fmt(op, f),
112            BinaryOp::CmpOp(op) => fmt::Display::fmt(op, f),
113            BinaryOp::Assignment { op } => {
114                if let Some(op) = op {
115                    fmt::Display::fmt(op, f)?;
116                }
117                f.write_str("=")?;
118                Ok(())
119            }
120        }
121    }
122}