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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
use crate::nodes::{BinaryOperator, Expression, Token, Variable};
/// Represents compound assignment operators (e.g., `+=`, `-=`, etc.).
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum CompoundOperator {
/// Addition and assignment (`+=`)
Plus,
/// Subtraction and assignment (`-=`)
Minus,
/// Multiplication and assignment (`*=`)
Asterisk,
/// Division and assignment (`/=`)
Slash,
/// Floor division and assignment (`//=`)
DoubleSlash,
/// Modulo and assignment (`%=`)
Percent,
/// Exponentiation and assignment (`^=`)
Caret,
/// Concatenation and assignment (`..=`)
Concat,
}
impl CompoundOperator {
/// Returns the string representation of the operator.
pub fn to_str(&self) -> &'static str {
match self {
Self::Plus => "+=",
Self::Minus => "-=",
Self::Asterisk => "*=",
Self::Slash => "/=",
Self::DoubleSlash => "//=",
Self::Percent => "%=",
Self::Caret => "^=",
Self::Concat => "..=",
}
}
/// Converts this compound operator to its corresponding binary operator.
pub fn to_binary_operator(&self) -> BinaryOperator {
match self {
Self::Plus => BinaryOperator::Plus,
Self::Minus => BinaryOperator::Minus,
Self::Asterisk => BinaryOperator::Asterisk,
Self::Slash => BinaryOperator::Slash,
Self::DoubleSlash => BinaryOperator::DoubleSlash,
Self::Percent => BinaryOperator::Percent,
Self::Caret => BinaryOperator::Caret,
Self::Concat => BinaryOperator::Concat,
}
}
}
/// Tokens associated with a compound assignment statement.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CompoundAssignTokens {
/// The operator token for the compound assignment.
pub operator: Token,
}
impl CompoundAssignTokens {
super::impl_token_fns!(target = [operator]);
}
/// Represents a compound assignment statement (e.g., `a += 1`).
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CompoundAssignStatement {
operator: CompoundOperator,
variable: Variable,
value: Expression,
tokens: Option<CompoundAssignTokens>,
}
impl CompoundAssignStatement {
/// Creates a new compound assignment statement.
pub fn new<V: Into<Variable>, E: Into<Expression>>(
operator: CompoundOperator,
variable: V,
value: E,
) -> Self {
Self {
operator,
variable: variable.into(),
value: value.into(),
tokens: None,
}
}
/// Sets the tokens for this compound assignment statement.
pub fn with_tokens(mut self, tokens: CompoundAssignTokens) -> Self {
self.tokens = Some(tokens);
self
}
/// Sets the tokens for this compound assignment statement.
#[inline]
pub fn set_tokens(&mut self, tokens: CompoundAssignTokens) {
self.tokens = Some(tokens);
}
/// Returns the tokens for this compound assignment statement, if any.
#[inline]
pub fn get_tokens(&self) -> Option<&CompoundAssignTokens> {
self.tokens.as_ref()
}
/// Returns the compound operator used in this statement.
#[inline]
pub fn get_operator(&self) -> CompoundOperator {
self.operator
}
/// Returns the variable being assigned to.
#[inline]
pub fn get_variable(&self) -> &Variable {
&self.variable
}
/// Returns the value expression in the assignment.
#[inline]
pub fn get_value(&self) -> &Expression {
&self.value
}
/// Extracts the variable and value from this statement.
#[inline]
pub fn extract_assignment(self) -> (Variable, Expression) {
(self.variable, self.value)
}
/// Returns a mutable reference to the variable.
#[inline]
pub fn mutate_variable(&mut self) -> &mut Variable {
&mut self.variable
}
/// Returns a mutable reference to the value expression.
#[inline]
pub fn mutate_value(&mut self) -> &mut Expression {
&mut self.value
}
/// Returns a mutable reference to the first token for this statement, creating it if missing.
pub fn mutate_first_token(&mut self) -> &mut Token {
self.variable.mutate_first_token()
}
/// Returns a mutable reference to the last token for this statement,
/// creating it if missing.
pub fn mutate_last_token(&mut self) -> &mut Token {
self.value.mutate_last_token()
}
super::impl_token_fns!(iter = [tokens]);
}