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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
use super::*;
fn int_expr(literal: crate::typed_ast::IntegerLiteral) -> crate::typed_ast::ConstExpr {
use crate::typed_ast::{
AddExpr, AndExpr, ConstExpr, Literal, MultExpr, OrExpr, PrimaryExpr, ShiftExpr, UnaryExpr,
XorExpr,
};
ConstExpr(OrExpr::XorExpr(XorExpr::AndExpr(AndExpr::ShiftExpr(
ShiftExpr::AddExpr(AddExpr::MultExpr(MultExpr::UnaryExpr(
UnaryExpr::PrimaryExpr(PrimaryExpr::Literal(Literal::IntegerLiteral(literal))),
))),
))))
}
fn binary_expr() -> crate::typed_ast::ConstExpr {
crate::typed_ast::ConstExpr(crate::typed_ast::OrExpr::OrExpr(
Box::new(crate::typed_ast::OrExpr::XorExpr(
crate::typed_ast::XorExpr::AndExpr(crate::typed_ast::AndExpr::ShiftExpr(
crate::typed_ast::ShiftExpr::AddExpr(crate::typed_ast::AddExpr::MultExpr(
crate::typed_ast::MultExpr::UnaryExpr(
crate::typed_ast::UnaryExpr::PrimaryExpr(
crate::typed_ast::PrimaryExpr::Literal(
crate::typed_ast::Literal::IntegerLiteral(
crate::typed_ast::IntegerLiteral::DecNumber("1".to_string()),
),
),
),
),
)),
)),
)),
crate::typed_ast::XorExpr::AndExpr(crate::typed_ast::AndExpr::ShiftExpr(
crate::typed_ast::ShiftExpr::AddExpr(crate::typed_ast::AddExpr::MultExpr(
crate::typed_ast::MultExpr::UnaryExpr(crate::typed_ast::UnaryExpr::PrimaryExpr(
crate::typed_ast::PrimaryExpr::Literal(
crate::typed_ast::Literal::IntegerLiteral(
crate::typed_ast::IntegerLiteral::DecNumber("2".to_string()),
),
),
)),
)),
)),
))
}
#[test]
fn const_expr_to_i64_handles_literals_and_rejects_composed_forms() {
assert_eq!(
const_expr_to_i64(
&int_expr(crate::typed_ast::IntegerLiteral::BinNumber(
"0B1010".to_string(),
))
.into()
),
Some(10)
);
assert_eq!(
const_expr_to_i64(
&int_expr(crate::typed_ast::IntegerLiteral::OctNumber(
"0o17".to_string(),
))
.into()
),
Some(15)
);
assert_eq!(
const_expr_to_i64(
&int_expr(crate::typed_ast::IntegerLiteral::DecNumber(
"42".to_string(),
))
.into()
),
Some(42)
);
assert_eq!(
const_expr_to_i64(
&int_expr(crate::typed_ast::IntegerLiteral::HexNumber(
"0x1f".to_string(),
))
.into()
),
Some(31)
);
assert_eq!(const_expr_to_i64(&binary_expr().into()), None);
let negative = crate::typed_ast::ConstExpr(crate::typed_ast::OrExpr::XorExpr(
crate::typed_ast::XorExpr::AndExpr(crate::typed_ast::AndExpr::ShiftExpr(
crate::typed_ast::ShiftExpr::AddExpr(crate::typed_ast::AddExpr::MultExpr(
crate::typed_ast::MultExpr::UnaryExpr(crate::typed_ast::UnaryExpr::UnaryExpr(
crate::typed_ast::UnaryOperator::Sub,
crate::typed_ast::PrimaryExpr::Literal(
crate::typed_ast::Literal::IntegerLiteral(
crate::typed_ast::IntegerLiteral::DecNumber("7".to_string()),
),
),
)),
)),
)),
));
assert_eq!(const_expr_to_i64(&negative.into()), Some(-7));
}
#[test]
fn conversion_covers_recursive_expr_and_literal_variants() {
let scoped = crate::typed_ast::ScopedName {
scoped_name: Some(Box::new(crate::typed_ast::ScopedName {
scoped_name: None,
identifier: crate::typed_ast::Identifier("demo".to_string()),
node_text: "demo".to_string(),
})),
identifier: crate::typed_ast::Identifier("VALUE".to_string()),
node_text: "::demo::VALUE".to_string(),
};
let nested = crate::typed_ast::ConstExpr(crate::typed_ast::OrExpr::XorExpr(
crate::typed_ast::XorExpr::XorExpr(
Box::new(crate::typed_ast::XorExpr::AndExpr(crate::typed_ast::AndExpr::AndExpr(
Box::new(crate::typed_ast::AndExpr::ShiftExpr(
crate::typed_ast::ShiftExpr::LeftShiftExpr(
Box::new(crate::typed_ast::ShiftExpr::RightShiftExpr(
Box::new(crate::typed_ast::ShiftExpr::AddExpr(
crate::typed_ast::AddExpr::AddExpr(
Box::new(crate::typed_ast::AddExpr::SubExpr(
Box::new(crate::typed_ast::AddExpr::MultExpr(
crate::typed_ast::MultExpr::MultExpr(
Box::new(crate::typed_ast::MultExpr::DivExpr(
Box::new(crate::typed_ast::MultExpr::ModExpr(
Box::new(crate::typed_ast::MultExpr::UnaryExpr(
crate::typed_ast::UnaryExpr::UnaryExpr(
crate::typed_ast::UnaryOperator::Add,
crate::typed_ast::PrimaryExpr::ConstExpr(
Box::new(int_expr(
crate::typed_ast::IntegerLiteral::BinNumber(
"0b1".to_string(),
),
)),
),
),
)),
crate::typed_ast::UnaryExpr::PrimaryExpr(
crate::typed_ast::PrimaryExpr::Literal(
crate::typed_ast::Literal::FloatingPtLiteral(
crate::typed_ast::FloatingPtLiteral {
sign: Some(crate::typed_ast::IntegerSign::Minus),
integer: crate::typed_ast::DecNumber(
"1".to_string(),
),
fraction: crate::typed_ast::DecNumber(
"5".to_string(),
),
},
),
),
),
)),
crate::typed_ast::UnaryExpr::PrimaryExpr(
crate::typed_ast::PrimaryExpr::Literal(
crate::typed_ast::Literal::CharLiteral(
"'a'".to_string(),
),
),
),
)),
crate::typed_ast::UnaryExpr::PrimaryExpr(
crate::typed_ast::PrimaryExpr::Literal(
crate::typed_ast::Literal::WideCharacterLiteral(
"L'a'".to_string(),
),
),
),
),
)),
crate::typed_ast::MultExpr::UnaryExpr(
crate::typed_ast::UnaryExpr::PrimaryExpr(
crate::typed_ast::PrimaryExpr::Literal(
crate::typed_ast::Literal::StringLiteral(
"\"hi\"".to_string(),
),
),
),
),
)),
crate::typed_ast::MultExpr::UnaryExpr(
crate::typed_ast::UnaryExpr::PrimaryExpr(
crate::typed_ast::PrimaryExpr::Literal(
crate::typed_ast::Literal::WideStringLiteral(
"L\"hi\"".to_string(),
),
),
),
),
),
)),
crate::typed_ast::AddExpr::MultExpr(crate::typed_ast::MultExpr::UnaryExpr(
crate::typed_ast::UnaryExpr::PrimaryExpr(
crate::typed_ast::PrimaryExpr::Literal(
crate::typed_ast::Literal::BooleanLiteral(
crate::typed_ast::BooleanLiteral::True,
),
),
),
)),
)),
crate::typed_ast::AddExpr::MultExpr(crate::typed_ast::MultExpr::UnaryExpr(
crate::typed_ast::UnaryExpr::PrimaryExpr(
crate::typed_ast::PrimaryExpr::ScopedName(scoped.clone()),
),
)),
),
)),
crate::typed_ast::ShiftExpr::AddExpr(crate::typed_ast::AddExpr::MultExpr(
crate::typed_ast::MultExpr::UnaryExpr(crate::typed_ast::UnaryExpr::UnaryExpr(
crate::typed_ast::UnaryOperator::Not,
crate::typed_ast::PrimaryExpr::Literal(crate::typed_ast::Literal::IntegerLiteral(
crate::typed_ast::IntegerLiteral::HexNumber("0x1".to_string()),
)),
)),
)),
))),
crate::typed_ast::AndExpr::ShiftExpr(crate::typed_ast::ShiftExpr::AddExpr(
crate::typed_ast::AddExpr::MultExpr(crate::typed_ast::MultExpr::UnaryExpr(
crate::typed_ast::UnaryExpr::PrimaryExpr(crate::typed_ast::PrimaryExpr::Literal(
crate::typed_ast::Literal::IntegerLiteral(
crate::typed_ast::IntegerLiteral::OctNumber("0o7".to_string()),
),
)),
)),
)),
),
));
let converted: ConstExpr = nested.into();
assert_eq!(const_expr_to_i64(&converted), None);
}