1use serde::{Deserialize, Serialize};
2
3use super::ScopedName;
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct ConstExpr(pub OrExpr);
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub enum OrExpr {
10 XorExpr(XorExpr),
11 OrExpr(Box<OrExpr>, XorExpr),
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub enum XorExpr {
16 AndExpr(AndExpr),
17 XorExpr(Box<XorExpr>, AndExpr),
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub enum AndExpr {
22 ShiftExpr(ShiftExpr),
23 AndExpr(Box<AndExpr>, ShiftExpr),
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
27pub enum ShiftExpr {
28 AddExpr(AddExpr),
29 LeftShiftExpr(Box<ShiftExpr>, AddExpr),
30 RightShiftExpr(Box<ShiftExpr>, AddExpr),
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize)]
34pub enum AddExpr {
35 MultExpr(MultExpr),
36 AddExpr(Box<AddExpr>, MultExpr),
37 SubExpr(Box<AddExpr>, MultExpr),
38}
39
40#[derive(Debug, Clone, Serialize, Deserialize)]
41pub enum MultExpr {
42 UnaryExpr(UnaryExpr),
43 MultExpr(Box<MultExpr>, UnaryExpr),
44 DivExpr(Box<MultExpr>, UnaryExpr),
45 ModExpr(Box<MultExpr>, UnaryExpr),
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize)]
49pub enum UnaryExpr {
50 UnaryExpr(UnaryOperator, PrimaryExpr),
51 PrimaryExpr(PrimaryExpr),
52}
53
54#[derive(Debug, Clone, Serialize, Deserialize)]
55pub enum PrimaryExpr {
56 ScopedName(ScopedName),
57 Literal(Literal),
58 ConstExpr(Box<ConstExpr>),
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize)]
62pub enum UnaryOperator {
63 Add,
64 Sub,
65 Not,
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize)]
69pub enum Literal {
70 IntegerLiteral(IntegerLiteral),
71 FloatingPtLiteral(FloatingPtLiteral),
72 CharLiteral(String),
73 WideCharacterLiteral(String),
74 StringLiteral(String),
75 WideStringLiteral(String),
76 BooleanLiteral(String),
77}
78
79#[derive(Debug, Clone, Serialize, Deserialize)]
80pub enum IntegerLiteral {
81 BinNumber(String),
82 OctNumber(String),
83 DecNumber(String),
84 HexNumber(String),
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
88pub struct FloatingPtLiteral {
89 pub sign: Option<IntegerSign>,
90 pub integer: DecNumber,
91 pub fraction: DecNumber,
92}
93
94#[derive(Debug, Clone, Serialize, Deserialize)]
95pub struct IntegerSign(pub String);
96
97#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct DecNumber(pub String);
99
100#[derive(Debug, Clone, Serialize, Deserialize)]
101pub struct PositiveIntConst(pub ConstExpr);
102
103pub fn const_expr_to_i64(expr: &ConstExpr) -> Option<i64> {
104 or_expr_to_i64(&expr.0)
105}
106
107fn or_expr_to_i64(expr: &OrExpr) -> Option<i64> {
108 match expr {
109 OrExpr::XorExpr(value) => xor_expr_to_i64(value),
110 OrExpr::OrExpr(_, _) => None,
111 }
112}
113
114fn xor_expr_to_i64(expr: &XorExpr) -> Option<i64> {
115 match expr {
116 XorExpr::AndExpr(value) => and_expr_to_i64(value),
117 XorExpr::XorExpr(_, _) => None,
118 }
119}
120
121fn and_expr_to_i64(expr: &AndExpr) -> Option<i64> {
122 match expr {
123 AndExpr::ShiftExpr(value) => shift_expr_to_i64(value),
124 AndExpr::AndExpr(_, _) => None,
125 }
126}
127
128fn shift_expr_to_i64(expr: &ShiftExpr) -> Option<i64> {
129 match expr {
130 ShiftExpr::AddExpr(value) => add_expr_to_i64(value),
131 ShiftExpr::LeftShiftExpr(_, _) => None,
132 ShiftExpr::RightShiftExpr(_, _) => None,
133 }
134}
135
136fn add_expr_to_i64(expr: &AddExpr) -> Option<i64> {
137 match expr {
138 AddExpr::MultExpr(value) => mult_expr_to_i64(value),
139 AddExpr::AddExpr(_, _) => None,
140 AddExpr::SubExpr(_, _) => None,
141 }
142}
143
144fn mult_expr_to_i64(expr: &MultExpr) -> Option<i64> {
145 match expr {
146 MultExpr::UnaryExpr(value) => unary_expr_to_i64(value),
147 MultExpr::MultExpr(_, _) => None,
148 MultExpr::DivExpr(_, _) => None,
149 MultExpr::ModExpr(_, _) => None,
150 }
151}
152
153fn unary_expr_to_i64(expr: &UnaryExpr) -> Option<i64> {
154 match expr {
155 UnaryExpr::PrimaryExpr(value) => primary_expr_to_i64(value),
156 UnaryExpr::UnaryExpr(op, value) => match op {
157 UnaryOperator::Add => primary_expr_to_i64(value),
158 UnaryOperator::Sub => primary_expr_to_i64(value).map(|value| -value),
159 UnaryOperator::Not => None,
160 },
161 }
162}
163
164fn primary_expr_to_i64(expr: &PrimaryExpr) -> Option<i64> {
165 match expr {
166 PrimaryExpr::Literal(value) => literal_to_i64(value),
167 PrimaryExpr::ScopedName(_) | PrimaryExpr::ConstExpr(_) => None,
168 }
169}
170
171fn literal_to_i64(value: &Literal) -> Option<i64> {
172 match value {
173 Literal::IntegerLiteral(lit) => parse_int_literal(lit),
174 _ => None,
175 }
176}
177
178fn parse_int_literal(value: &IntegerLiteral) -> Option<i64> {
179 match value {
180 IntegerLiteral::BinNumber(value) => parse_radix(value, 2),
181 IntegerLiteral::OctNumber(value) => parse_radix(value, 8),
182 IntegerLiteral::DecNumber(value) => parse_radix(value, 10),
183 IntegerLiteral::HexNumber(value) => parse_radix(value, 16),
184 }
185}
186
187fn parse_radix(value: &str, radix: u32) -> Option<i64> {
188 let cleaned = value.replace('_', "");
189 let trimmed = cleaned.trim();
190 let stripped = match radix {
191 2 => trimmed
192 .strip_prefix("0b")
193 .or_else(|| trimmed.strip_prefix("0B")),
194 8 => trimmed
195 .strip_prefix("0o")
196 .or_else(|| trimmed.strip_prefix("0O")),
197 16 => trimmed
198 .strip_prefix("0x")
199 .or_else(|| trimmed.strip_prefix("0X")),
200 _ => None,
201 };
202 let digits = stripped.unwrap_or(trimmed);
203 i64::from_str_radix(digits, radix).ok()
204}
205
206impl From<crate::typed_ast::ConstExpr> for ConstExpr {
207 fn from(value: crate::typed_ast::ConstExpr) -> Self {
208 Self(value.0.into())
209 }
210}
211
212impl From<crate::typed_ast::OrExpr> for OrExpr {
213 fn from(value: crate::typed_ast::OrExpr) -> Self {
214 match value {
215 crate::typed_ast::OrExpr::XorExpr(value) => Self::XorExpr(value.into()),
216 crate::typed_ast::OrExpr::OrExpr(left, right) => {
217 Self::OrExpr(Box::new((*left).into()), right.into())
218 }
219 }
220 }
221}
222
223impl From<crate::typed_ast::XorExpr> for XorExpr {
224 fn from(value: crate::typed_ast::XorExpr) -> Self {
225 match value {
226 crate::typed_ast::XorExpr::AndExpr(value) => Self::AndExpr(value.into()),
227 crate::typed_ast::XorExpr::XorExpr(left, right) => {
228 Self::XorExpr(Box::new((*left).into()), right.into())
229 }
230 }
231 }
232}
233
234impl From<crate::typed_ast::AndExpr> for AndExpr {
235 fn from(value: crate::typed_ast::AndExpr) -> Self {
236 match value {
237 crate::typed_ast::AndExpr::ShiftExpr(value) => Self::ShiftExpr(value.into()),
238 crate::typed_ast::AndExpr::AndExpr(left, right) => {
239 Self::AndExpr(Box::new((*left).into()), right.into())
240 }
241 }
242 }
243}
244
245impl From<crate::typed_ast::ShiftExpr> for ShiftExpr {
246 fn from(value: crate::typed_ast::ShiftExpr) -> Self {
247 match value {
248 crate::typed_ast::ShiftExpr::AddExpr(value) => Self::AddExpr(value.into()),
249 crate::typed_ast::ShiftExpr::LeftShiftExpr(left, right) => {
250 Self::LeftShiftExpr(Box::new((*left).into()), right.into())
251 }
252 crate::typed_ast::ShiftExpr::RightShiftExpr(left, right) => {
253 Self::RightShiftExpr(Box::new((*left).into()), right.into())
254 }
255 }
256 }
257}
258
259impl From<crate::typed_ast::AddExpr> for AddExpr {
260 fn from(value: crate::typed_ast::AddExpr) -> Self {
261 match value {
262 crate::typed_ast::AddExpr::MultExpr(value) => Self::MultExpr(value.into()),
263 crate::typed_ast::AddExpr::AddExpr(left, right) => {
264 Self::AddExpr(Box::new((*left).into()), right.into())
265 }
266 crate::typed_ast::AddExpr::SubExpr(left, right) => {
267 Self::SubExpr(Box::new((*left).into()), right.into())
268 }
269 }
270 }
271}
272
273impl From<crate::typed_ast::MultExpr> for MultExpr {
274 fn from(value: crate::typed_ast::MultExpr) -> Self {
275 match value {
276 crate::typed_ast::MultExpr::UnaryExpr(value) => Self::UnaryExpr(value.into()),
277 crate::typed_ast::MultExpr::MultExpr(left, right) => {
278 Self::MultExpr(Box::new((*left).into()), right.into())
279 }
280 crate::typed_ast::MultExpr::DivExpr(left, right) => {
281 Self::DivExpr(Box::new((*left).into()), right.into())
282 }
283 crate::typed_ast::MultExpr::ModExpr(left, right) => {
284 Self::ModExpr(Box::new((*left).into()), right.into())
285 }
286 }
287 }
288}
289
290impl From<crate::typed_ast::UnaryExpr> for UnaryExpr {
291 fn from(value: crate::typed_ast::UnaryExpr) -> Self {
292 match value {
293 crate::typed_ast::UnaryExpr::PrimaryExpr(value) => Self::PrimaryExpr(value.into()),
294 crate::typed_ast::UnaryExpr::UnaryExpr(op, value) => {
295 Self::UnaryExpr(op.into(), value.into())
296 }
297 }
298 }
299}
300
301impl From<crate::typed_ast::PrimaryExpr> for PrimaryExpr {
302 fn from(value: crate::typed_ast::PrimaryExpr) -> Self {
303 match value {
304 crate::typed_ast::PrimaryExpr::ScopedName(value) => Self::ScopedName(value.into()),
305 crate::typed_ast::PrimaryExpr::Literal(value) => Self::Literal(value.into()),
306 crate::typed_ast::PrimaryExpr::ConstExpr(value) => {
307 Self::ConstExpr(Box::new((*value).into()))
308 }
309 }
310 }
311}
312
313impl From<crate::typed_ast::UnaryOperator> for UnaryOperator {
314 fn from(value: crate::typed_ast::UnaryOperator) -> Self {
315 match value {
316 crate::typed_ast::UnaryOperator::Add => Self::Add,
317 crate::typed_ast::UnaryOperator::Sub => Self::Sub,
318 crate::typed_ast::UnaryOperator::Not => Self::Not,
319 }
320 }
321}
322
323impl From<crate::typed_ast::Literal> for Literal {
324 fn from(value: crate::typed_ast::Literal) -> Self {
325 match value {
326 crate::typed_ast::Literal::IntegerLiteral(value) => Self::IntegerLiteral(value.into()),
327 crate::typed_ast::Literal::FloatingPtLiteral(value) => {
328 Self::FloatingPtLiteral(value.into())
329 }
330 crate::typed_ast::Literal::CharLiteral(value) => Self::CharLiteral(value),
331 crate::typed_ast::Literal::WideCharacterLiteral(value) => {
332 Self::WideCharacterLiteral(value)
333 }
334 crate::typed_ast::Literal::StringLiteral(value) => Self::StringLiteral(value),
335 crate::typed_ast::Literal::WideStringLiteral(value) => Self::WideStringLiteral(value),
336 crate::typed_ast::Literal::BooleanLiteral(value) => Self::BooleanLiteral(value),
337 }
338 }
339}
340
341impl From<crate::typed_ast::IntegerLiteral> for IntegerLiteral {
342 fn from(value: crate::typed_ast::IntegerLiteral) -> Self {
343 match value {
344 crate::typed_ast::IntegerLiteral::BinNumber(value) => Self::BinNumber(value),
345 crate::typed_ast::IntegerLiteral::OctNumber(value) => Self::OctNumber(value),
346 crate::typed_ast::IntegerLiteral::DecNumber(value) => Self::DecNumber(value),
347 crate::typed_ast::IntegerLiteral::HexNumber(value) => Self::HexNumber(value),
348 }
349 }
350}
351
352impl From<crate::typed_ast::FloatingPtLiteral> for FloatingPtLiteral {
353 fn from(value: crate::typed_ast::FloatingPtLiteral) -> Self {
354 Self {
355 sign: value.sign.map(Into::into),
356 integer: value.integer.into(),
357 fraction: value.fraction.into(),
358 }
359 }
360}
361
362impl From<crate::typed_ast::IntegerSign> for IntegerSign {
363 fn from(value: crate::typed_ast::IntegerSign) -> Self {
364 Self(value.0)
365 }
366}
367
368impl From<crate::typed_ast::DecNumber> for DecNumber {
369 fn from(value: crate::typed_ast::DecNumber) -> Self {
370 Self(value.0)
371 }
372}
373
374impl From<crate::typed_ast::PositiveIntConst> for PositiveIntConst {
375 fn from(value: crate::typed_ast::PositiveIntConst) -> Self {
376 Self(value.0.into())
377 }
378}
379
380impl From<crate::typed_ast::FixedArraySize> for PositiveIntConst {
381 fn from(value: crate::typed_ast::FixedArraySize) -> Self {
382 value.0.into()
383 }
384}