1+ use derive_more:: Display ;
2+ use serde:: { Deserialize , Serialize } ;
3+ use full_moon_derive:: { Node , Visit } ;
4+ use crate :: ast:: { Expression , Var } ;
5+ use crate :: tokenizer:: { Symbol , TokenReference } ;
6+
7+ #[ derive( Clone , Debug , Display , PartialEq , Eq , Node , Visit ) ]
8+ #[ cfg_attr( feature = "serde" , derive( Deserialize , Serialize ) ) ]
9+ #[ non_exhaustive]
10+ #[ allow( missing_docs) ]
11+ #[ display( "{_0}" ) ]
12+ /// Compound operators, such as X += Y or X -= Y
13+ pub enum CompoundOp {
14+ PlusEqual ( TokenReference ) ,
15+ MinusEqual ( TokenReference ) ,
16+ StarEqual ( TokenReference ) ,
17+ SlashEqual ( TokenReference ) ,
18+ CaretEqual ( TokenReference ) ,
19+
20+ // luau sepcific
21+ DoubleSlashEqual ( TokenReference ) ,
22+ PercentEqual ( TokenReference ) ,
23+ TwoDotsEqual ( TokenReference ) ,
24+
25+ // cfxlua sepcific
26+ LeftShift ( TokenReference ) ,
27+ RightShift ( TokenReference ) ,
28+ BitwiseAndAssignment ( TokenReference ) ,
29+ BitwiseOrAssignment ( TokenReference ) ,
30+ }
31+
32+ impl CompoundOp {
33+ /// The token associated with the operator
34+ pub fn token ( & self ) -> & TokenReference {
35+ match self {
36+ Self :: PlusEqual ( token)
37+ | Self :: MinusEqual ( token)
38+ | Self :: StarEqual ( token)
39+ | Self :: SlashEqual ( token)
40+ | Self :: DoubleSlashEqual ( token)
41+ | Self :: PercentEqual ( token)
42+ | Self :: CaretEqual ( token)
43+ | Self :: TwoDotsEqual ( token)
44+ | Self :: LeftShift ( token)
45+ | Self :: RightShift ( token)
46+ | Self :: BitwiseAndAssignment ( token)
47+ | Self :: BitwiseOrAssignment ( token) => token,
48+ }
49+ }
50+
51+ pub ( crate ) fn from_token ( token : TokenReference ) -> Self {
52+ if token. is_symbol ( Symbol :: PlusEqual ) {
53+ return Self :: PlusEqual ( token)
54+ } else if token. is_symbol ( Symbol :: MinusEqual ) {
55+ return Self :: MinusEqual ( token)
56+ } else if token. is_symbol ( Symbol :: StarEqual ) {
57+ return Self :: StarEqual ( token)
58+ } else if token. is_symbol ( Symbol :: SlashEqual ) {
59+ return Self :: SlashEqual ( token)
60+ } else if token. is_symbol ( Symbol :: CaretEqual ) {
61+ return Self :: CaretEqual ( token)
62+ }
63+
64+ #[ cfg( feature = "luau" ) ]
65+ if token. is_symbol ( Symbol :: DoubleSlashEqual ) {
66+ return Self :: DoubleSlashEqual ( token)
67+ } else if token. is_symbol ( Symbol :: PercentEqual ) {
68+ return Self :: PercentEqual ( token)
69+ } else if token. is_symbol ( Symbol :: TwoDotsEqual ) {
70+ return Self :: TwoDotsEqual ( token)
71+ }
72+
73+ #[ cfg( feature = "cfxlua" ) ]
74+ if token. is_symbol ( Symbol :: LeftShift ) {
75+ return Self :: LeftShift ( token)
76+ } else if token. is_symbol ( Symbol :: RightShift ) {
77+ return Self :: RightShift ( token)
78+ } else if token. is_symbol ( Symbol :: BitwiseAndAssignment ) {
79+ return Self :: BitwiseAndAssignment ( token)
80+ } else if token. is_symbol ( Symbol :: BitwiseOrAssignment ) {
81+ return Self :: BitwiseOrAssignment ( token)
82+ }
83+
84+ unreachable ! ( "converting an unknown token into a compound operator" )
85+ }
86+ }
87+
88+
89+ /// A Compound Assignment statement, such as `x += 1` or `x -= 1`
90+ #[ derive( Clone , Debug , Display , PartialEq , Node , Visit ) ]
91+ #[ cfg_attr( feature = "serde" , derive( Deserialize , Serialize ) ) ]
92+ #[ display( "{lhs}{compound_operator}{rhs}" ) ]
93+ pub struct CompoundAssignment {
94+ pub ( crate ) lhs : Var ,
95+ pub ( crate ) compound_operator : CompoundOp ,
96+ pub ( crate ) rhs : Expression ,
97+ }
98+
99+ impl CompoundAssignment {
100+ /// Creates a new CompoundAssignment from the left and right hand side
101+ pub fn new ( lhs : Var , compound_operator : CompoundOp , rhs : Expression ) -> Self {
102+ Self {
103+ lhs,
104+ compound_operator,
105+ rhs,
106+ }
107+ }
108+
109+ /// The variable assigned to, the `x` part of `x += 1`
110+ pub fn lhs ( & self ) -> & Var {
111+ & self . lhs
112+ }
113+
114+ /// The operator used, the `+=` part of `x += 1`
115+ pub fn compound_operator ( & self ) -> & CompoundOp {
116+ & self . compound_operator
117+ }
118+
119+ /// The value being assigned, the `1` part of `x += 1`
120+ pub fn rhs ( & self ) -> & Expression {
121+ & self . rhs
122+ }
123+
124+ /// Returns a new CompoundAssignment with the given variable being assigned to
125+ pub fn with_lhs ( self , lhs : Var ) -> Self {
126+ Self { lhs, ..self }
127+ }
128+
129+ /// Returns a new CompoundAssignment with the given operator used
130+ pub fn with_compound_operator ( self , compound_operator : CompoundOp ) -> Self {
131+ Self {
132+ compound_operator,
133+ ..self
134+ }
135+ }
136+
137+ /// Returns a new CompoundAssignment with the given value being assigned
138+ pub fn with_rhs ( self , rhs : Expression ) -> Self {
139+ Self { rhs, ..self }
140+ }
141+ }
0 commit comments