1use serde::Serialize;
2use strum::Display;
3
4use mago_span::HasSpan;
5use mago_span::Span;
6
7use crate::ast::ast::expression::Expression;
8use crate::token::GetPrecedence;
9use crate::token::Precedence;
10
11#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord, Display)]
12#[serde(tag = "type", content = "value")]
13pub enum UnaryPrefixOperator<'arena> {
14 ErrorControl(Span), Reference(Span), ArrayCast(Span, &'arena str), BoolCast(Span, &'arena str), BooleanCast(Span, &'arena str), DoubleCast(Span, &'arena str), RealCast(Span, &'arena str), FloatCast(Span, &'arena str), IntCast(Span, &'arena str), IntegerCast(Span, &'arena str), ObjectCast(Span, &'arena str), UnsetCast(Span, &'arena str), StringCast(Span, &'arena str), BinaryCast(Span, &'arena str), VoidCast(Span, &'arena str), BitwiseNot(Span), Not(Span), PreIncrement(Span), PreDecrement(Span), Plus(Span), Negation(Span), }
36
37#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord, Display)]
38#[serde(tag = "type", content = "value")]
39pub enum UnaryPostfixOperator {
40 PostIncrement(Span), PostDecrement(Span), }
43
44#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
45pub struct UnaryPrefix<'arena> {
46 pub operator: UnaryPrefixOperator<'arena>,
47 pub operand: &'arena Expression<'arena>,
48}
49
50#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
51pub struct UnaryPostfix<'arena> {
52 pub operand: &'arena Expression<'arena>,
53 pub operator: UnaryPostfixOperator,
54}
55
56impl<'arena> UnaryPrefixOperator<'arena> {
57 #[inline]
58 #[must_use]
59 pub const fn is_error_control(&self) -> bool {
60 matches!(self, Self::ErrorControl(_))
61 }
62
63 #[inline]
64 #[must_use]
65 pub const fn is_constant(&self) -> bool {
66 matches!(
67 self,
68 Self::BitwiseNot(_)
69 | Self::Not(_)
70 | Self::PreIncrement(_)
71 | Self::PreDecrement(_)
72 | Self::Plus(_)
73 | Self::Negation(_)
74 )
75 }
76
77 #[inline]
78 #[must_use]
79 pub const fn is_cast(&self) -> bool {
80 matches!(
81 self,
82 Self::ArrayCast(_, _)
83 | Self::BoolCast(_, _)
84 | Self::BooleanCast(_, _)
85 | Self::DoubleCast(_, _)
86 | Self::RealCast(_, _)
87 | Self::FloatCast(_, _)
88 | Self::IntCast(_, _)
89 | Self::IntegerCast(_, _)
90 | Self::ObjectCast(_, _)
91 | Self::UnsetCast(_, _)
92 | Self::StringCast(_, _)
93 | Self::BinaryCast(_, _)
94 | Self::VoidCast(_, _)
95 )
96 }
97
98 #[inline]
99 #[must_use]
100 pub const fn is_reference(&self) -> bool {
101 matches!(self, Self::Reference(_))
102 }
103
104 #[inline]
105 #[must_use]
106 pub const fn is_arithmetic(&self) -> bool {
107 matches!(self, Self::Plus(_) | Self::Negation(_) | Self::PreIncrement(_) | Self::PreDecrement(_))
108 }
109
110 #[inline]
111 #[must_use]
112 pub const fn is_increment_or_decrement(&self) -> bool {
113 matches!(self, Self::PreIncrement(_) | Self::PreDecrement(_))
114 }
115
116 #[inline]
117 #[must_use]
118 pub const fn is_not(&self) -> bool {
119 matches!(self, Self::Not(_))
120 }
121
122 #[inline]
123 #[must_use]
124 pub fn as_str(&self) -> &'arena str {
125 match self {
126 UnaryPrefixOperator::ErrorControl(_) => "@",
127 UnaryPrefixOperator::Reference(_) => "&",
128 UnaryPrefixOperator::ArrayCast(_, value)
129 | UnaryPrefixOperator::BoolCast(_, value)
130 | UnaryPrefixOperator::BooleanCast(_, value)
131 | UnaryPrefixOperator::DoubleCast(_, value)
132 | UnaryPrefixOperator::RealCast(_, value)
133 | UnaryPrefixOperator::FloatCast(_, value)
134 | UnaryPrefixOperator::IntCast(_, value)
135 | UnaryPrefixOperator::IntegerCast(_, value)
136 | UnaryPrefixOperator::ObjectCast(_, value)
137 | UnaryPrefixOperator::UnsetCast(_, value)
138 | UnaryPrefixOperator::StringCast(_, value)
139 | UnaryPrefixOperator::BinaryCast(_, value)
140 | UnaryPrefixOperator::VoidCast(_, value) => value,
141 UnaryPrefixOperator::BitwiseNot(_) => "~",
142 UnaryPrefixOperator::Not(_) => "!",
143 UnaryPrefixOperator::PreIncrement(_) => "++",
144 UnaryPrefixOperator::PreDecrement(_) => "--",
145 UnaryPrefixOperator::Plus(_) => "+",
146 UnaryPrefixOperator::Negation(_) => "-",
147 }
148 }
149
150 #[inline]
151 #[must_use]
152 pub const fn is_same_as(&self, other: &Self) -> bool {
153 matches!(
154 (self, other),
155 (Self::ErrorControl(_), Self::ErrorControl(_))
156 | (Self::Reference(_), Self::Reference(_))
157 | (Self::ArrayCast(_, _), Self::ArrayCast(_, _))
158 | (Self::BoolCast(_, _), Self::BoolCast(_, _))
159 | (Self::BooleanCast(_, _), Self::BooleanCast(_, _))
160 | (Self::DoubleCast(_, _), Self::DoubleCast(_, _))
161 | (Self::RealCast(_, _), Self::RealCast(_, _))
162 | (Self::FloatCast(_, _), Self::FloatCast(_, _))
163 | (Self::IntCast(_, _), Self::IntCast(_, _))
164 | (Self::IntegerCast(_, _), Self::IntegerCast(_, _))
165 | (Self::ObjectCast(_, _), Self::ObjectCast(_, _))
166 | (Self::UnsetCast(_, _), Self::UnsetCast(_, _))
167 | (Self::StringCast(_, _), Self::StringCast(_, _))
168 | (Self::BinaryCast(_, _), Self::BinaryCast(_, _))
169 | (Self::VoidCast(_, _), Self::VoidCast(_, _))
170 | (Self::BitwiseNot(_), Self::BitwiseNot(_))
171 | (Self::Not(_), Self::Not(_))
172 | (Self::PreIncrement(_), Self::PreIncrement(_))
173 | (Self::PreDecrement(_), Self::PreDecrement(_))
174 | (Self::Plus(_), Self::Plus(_))
175 | (Self::Negation(_), Self::Negation(_))
176 )
177 }
178}
179
180impl GetPrecedence for UnaryPrefixOperator<'_> {
181 fn precedence(&self) -> Precedence {
182 match self {
183 Self::Reference(_) => Precedence::Reference,
184 Self::ErrorControl(_) => Precedence::ErrorControl,
185 Self::PreIncrement(_) | Self::PreDecrement(_) => Precedence::IncDec,
186 _ => Precedence::Unary,
187 }
188 }
189}
190
191impl UnaryPostfixOperator {
192 #[inline]
193 #[must_use]
194 pub const fn is_constant(&self) -> bool {
195 match self {
196 Self::PostIncrement(_) | Self::PostDecrement(_) => false,
197 }
198 }
199
200 #[inline]
201 #[must_use]
202 pub const fn as_str<'a>(&self) -> &'a str {
203 match self {
204 UnaryPostfixOperator::PostIncrement(_) => "++",
205 UnaryPostfixOperator::PostDecrement(_) => "--",
206 }
207 }
208
209 #[inline]
210 #[must_use]
211 pub const fn is_same_as(&self, other: &Self) -> bool {
212 matches!(
213 (self, other),
214 (Self::PostIncrement(_), Self::PostIncrement(_)) | (Self::PostDecrement(_), Self::PostDecrement(_))
215 )
216 }
217}
218
219impl GetPrecedence for UnaryPostfixOperator {
220 fn precedence(&self) -> Precedence {
221 match self {
222 Self::PostIncrement(_) | Self::PostDecrement(_) => Precedence::Unary,
223 }
224 }
225}
226
227impl HasSpan for UnaryPrefixOperator<'_> {
228 fn span(&self) -> Span {
229 match self {
230 Self::ErrorControl(span) => *span,
231 Self::Reference(span) => *span,
232 Self::ArrayCast(span, ..) => *span,
233 Self::BoolCast(span, ..) => *span,
234 Self::BooleanCast(span, ..) => *span,
235 Self::DoubleCast(span, ..) => *span,
236 Self::RealCast(span, ..) => *span,
237 Self::FloatCast(span, ..) => *span,
238 Self::IntCast(span, ..) => *span,
239 Self::IntegerCast(span, ..) => *span,
240 Self::ObjectCast(span, ..) => *span,
241 Self::UnsetCast(span, ..) => *span,
242 Self::StringCast(span, ..) => *span,
243 Self::BinaryCast(span, ..) => *span,
244 Self::VoidCast(span, ..) => *span,
245 Self::BitwiseNot(span) => *span,
246 Self::Not(span) => *span,
247 Self::PreIncrement(span) => *span,
248 Self::PreDecrement(span) => *span,
249 Self::Plus(span) => *span,
250 Self::Negation(span) => *span,
251 }
252 }
253}
254
255impl HasSpan for UnaryPostfixOperator {
256 fn span(&self) -> Span {
257 match self {
258 Self::PostIncrement(span) => *span,
259 Self::PostDecrement(span) => *span,
260 }
261 }
262}
263
264impl HasSpan for UnaryPrefix<'_> {
265 fn span(&self) -> Span {
266 self.operator.span().join(self.operand.span())
267 }
268}
269
270impl HasSpan for UnaryPostfix<'_> {
271 fn span(&self) -> Span {
272 self.operand.span().join(self.operator.span())
273 }
274}