mxmlextrema_as3parser/operator/
operator.rs

1use crate::ns::*;
2use serde::{Serialize, Deserialize};
3
4/// Represents an ActionScript operator.
5#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
6pub enum Operator {
7    PostIncrement,
8    PostDecrement,
9    NonNull,
10    Delete,
11    Void,
12    Typeof,
13    Await,
14    Yield,
15    PreIncrement,
16    PreDecrement,
17    Positive,
18    Negative,
19    BitwiseNot,
20    LogicalNot,
21
22    Power,
23    Multiply,
24    Divide,
25    Remainder,
26    Add,
27    Subtract,
28    ShiftLeft,
29    ShiftRight,
30    ShiftRightUnsigned,
31    Lt,
32    Gt,
33    Le,
34    Ge,
35    Instanceof,
36    In,
37    NotIn,
38    Is,
39    IsNot,
40    As,
41    Equals,
42    NotEquals,
43    StrictEquals,
44    StrictNotEquals,
45    BitwiseAnd,
46    BitwiseXor,
47    BitwiseOr,
48    LogicalAnd,
49    LogicalXor,
50    LogicalOr,
51    NullCoalescing,
52}
53
54/// Represents binary operator associativity.
55#[derive(Copy, Clone, PartialEq, Eq)]
56pub enum BinaryAssociativity {
57    LeftToRight,
58    RightToLeft,
59}
60
61/// Represents an ActionScript binary operator.
62#[derive(Copy, Clone, PartialEq, Eq)]
63pub struct BinaryOperator(pub Operator, pub OperatorPrecedence, pub BinaryAssociativity);
64
65impl BinaryOperator {
66    pub fn operator(&self) -> Operator {
67        self.0
68    }
69
70    pub fn precedence(&self) -> OperatorPrecedence {
71        self.1
72    }
73
74    pub fn associativity(&self) -> BinaryAssociativity {
75        self.2
76    }
77
78    pub fn right_precedence(&self) -> OperatorPrecedence {
79        if self.operator() == Operator::NullCoalescing {
80            OperatorPrecedence::BitwiseOr
81        } else {
82            self.precedence().add(if self.associativity() == BinaryAssociativity::LeftToRight { 1 } else { 0 }).unwrap()
83        }
84    }
85}
86
87impl TryFrom<Operator> for BinaryOperator {
88    type Error = ();
89    /// Constructs `BinaryOperator` from abstract operator.
90    fn try_from(value: Operator) -> Result<Self, Self::Error> {
91        match value {
92            Operator::Multiply => Ok(BinaryOperator(value, OperatorPrecedence::Multiplicative, BinaryAssociativity::LeftToRight)),
93            Operator::Divide => Ok(BinaryOperator(value, OperatorPrecedence::Multiplicative, BinaryAssociativity::LeftToRight)),
94            Operator::Remainder => Ok(BinaryOperator(value, OperatorPrecedence::Multiplicative, BinaryAssociativity::LeftToRight)),
95            Operator::Add => Ok(BinaryOperator(value, OperatorPrecedence::Additive, BinaryAssociativity::LeftToRight)),
96            Operator::Subtract => Ok(BinaryOperator(value, OperatorPrecedence::Additive, BinaryAssociativity::LeftToRight)),
97            Operator::ShiftLeft => Ok(BinaryOperator(value, OperatorPrecedence::Shift, BinaryAssociativity::LeftToRight)),
98            Operator::ShiftRight => Ok(BinaryOperator(value, OperatorPrecedence::Shift, BinaryAssociativity::LeftToRight)),
99            Operator::ShiftRightUnsigned => Ok(BinaryOperator(value, OperatorPrecedence::Shift, BinaryAssociativity::LeftToRight)),
100            Operator::Lt => Ok(BinaryOperator(value, OperatorPrecedence::Relational, BinaryAssociativity::LeftToRight)),
101            Operator::Gt => Ok(BinaryOperator(value, OperatorPrecedence::Relational, BinaryAssociativity::LeftToRight)),
102            Operator::Le => Ok(BinaryOperator(value, OperatorPrecedence::Relational, BinaryAssociativity::LeftToRight)),
103            Operator::Ge => Ok(BinaryOperator(value, OperatorPrecedence::Relational, BinaryAssociativity::LeftToRight)),
104            Operator::As => Ok(BinaryOperator(value, OperatorPrecedence::Relational, BinaryAssociativity::LeftToRight)),
105            Operator::In => Ok(BinaryOperator(value, OperatorPrecedence::Relational, BinaryAssociativity::LeftToRight)),
106            Operator::NotIn => Ok(BinaryOperator(value, OperatorPrecedence::Relational, BinaryAssociativity::LeftToRight)),
107            Operator::Instanceof => Ok(BinaryOperator(value, OperatorPrecedence::Relational, BinaryAssociativity::LeftToRight)),
108            Operator::Is => Ok(BinaryOperator(value, OperatorPrecedence::Relational, BinaryAssociativity::LeftToRight)),
109            Operator::IsNot => Ok(BinaryOperator(value, OperatorPrecedence::Relational, BinaryAssociativity::LeftToRight)),
110            Operator::Equals => Ok(BinaryOperator(value, OperatorPrecedence::Equality, BinaryAssociativity::LeftToRight)),
111            Operator::NotEquals => Ok(BinaryOperator(value, OperatorPrecedence::Equality, BinaryAssociativity::LeftToRight)),
112            Operator::StrictEquals => Ok(BinaryOperator(value, OperatorPrecedence::Equality, BinaryAssociativity::LeftToRight)),
113            Operator::StrictNotEquals => Ok(BinaryOperator(value, OperatorPrecedence::Equality, BinaryAssociativity::LeftToRight)),
114            Operator::BitwiseAnd => Ok(BinaryOperator(value, OperatorPrecedence::BitwiseAnd, BinaryAssociativity::LeftToRight)),
115            Operator::BitwiseXor => Ok(BinaryOperator(value, OperatorPrecedence::BitwiseXor, BinaryAssociativity::LeftToRight)),
116            Operator::BitwiseOr => Ok(BinaryOperator(value, OperatorPrecedence::BitwiseOr, BinaryAssociativity::LeftToRight)),
117            Operator::LogicalAnd => Ok(BinaryOperator(value, OperatorPrecedence::LogicalAnd, BinaryAssociativity::LeftToRight)),
118            Operator::LogicalXor => Ok(BinaryOperator(value, OperatorPrecedence::LogicalXor, BinaryAssociativity::LeftToRight)),
119            Operator::LogicalOr => Ok(BinaryOperator(value, OperatorPrecedence::LogicalOrAndOther, BinaryAssociativity::LeftToRight)),
120            Operator::NullCoalescing => Ok(BinaryOperator(value, OperatorPrecedence::LogicalOrAndOther, BinaryAssociativity::LeftToRight)),
121
122            Operator::Power => Ok(BinaryOperator(value, OperatorPrecedence::Exponentiation, BinaryAssociativity::RightToLeft)),
123
124            _ => Err(()),
125        }
126    }
127}