Skip to main content

yog_script_analyze/ast/
operator.rs

1//! An operator declared (`public static Vec operator +(Vec a, Vec b)`,
2//! `public static implicit operator Energy(i32 v)`): a static method named
3//! as the CLR names it (`op_Addition`, `op_Implicit`), so the checker,
4//! inheritance and the JVM treat it as any method.
5
6use yog_script_ids::clr;
7
8use super::{BinOp, Method, UnOp};
9
10/// Which operator a declaration is.
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum OperatorKind {
13    Binary(BinOp),
14    Unary(UnOp),
15    /// A conversion that happens by itself where its target is wanted.
16    Implicit,
17    /// A conversion written as a cast (`(Energy)n`).
18    Explicit,
19}
20
21#[derive(Debug, Clone, PartialEq)]
22pub struct Operator {
23    pub kind: OperatorKind,
24    /// Its method, named `kind.method_name()`.
25    pub method: Method,
26}
27
28impl OperatorKind {
29    /// Its method's name, the CLR's; none for an operator that can't be
30    /// declared (`&&`, `||`, `??`, `try`, `await`, `in`).
31    pub fn method_name(self) -> Option<&'static str> {
32        Some(match self {
33            OperatorKind::Binary(op) => match op {
34                BinOp::Add => clr::OP_ADDITION,
35                BinOp::Sub => clr::OP_SUBTRACTION,
36                BinOp::Mul => clr::OP_MULTIPLY,
37                BinOp::Div => clr::OP_DIVISION,
38                BinOp::Rem => clr::OP_MODULUS,
39                BinOp::BitAnd => clr::OP_BITWISE_AND,
40                BinOp::BitOr => clr::OP_BITWISE_OR,
41                BinOp::BitXor => clr::OP_EXCLUSIVE_OR,
42                BinOp::Shl => clr::OP_LEFT_SHIFT,
43                BinOp::Shr => clr::OP_RIGHT_SHIFT,
44                BinOp::Eq => clr::OP_EQUALITY,
45                BinOp::NotEq => clr::OP_INEQUALITY,
46                BinOp::Lt => clr::OP_LESS_THAN,
47                BinOp::LtEq => clr::OP_LESS_THAN_OR_EQUAL,
48                BinOp::Gt => clr::OP_GREATER_THAN,
49                BinOp::GtEq => clr::OP_GREATER_THAN_OR_EQUAL,
50                BinOp::Coalesce | BinOp::Or | BinOp::And | BinOp::In => return None,
51            },
52            OperatorKind::Unary(op) => match op {
53                UnOp::Neg => clr::OP_UNARY_NEGATION,
54                UnOp::Not => clr::OP_LOGICAL_NOT,
55                UnOp::BitNot => clr::OP_ONES_COMPLEMENT,
56                UnOp::Increment => clr::OP_INCREMENT,
57                UnOp::Decrement => clr::OP_DECREMENT,
58                UnOp::PostIncrement
59                | UnOp::PostDecrement
60                | UnOp::Try
61                | UnOp::Await
62                | UnOp::FromEnd => {
63                    return None;
64                }
65            },
66            OperatorKind::Implicit => clr::OP_IMPLICIT,
67            OperatorKind::Explicit => clr::OP_EXPLICIT,
68        })
69    }
70}