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