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