1#[macro_export]
2macro_rules! assert_expr_eq {
3 ($lhs:expr, $rhs:expr) => {{
4 assert_eq!($lhs, $rhs);
5 }};
6
7 ($lhs:expr, $rhs:expr; ignore span) => {{
8 let lhs = ($lhs).reset_spans();
11 let rhs = ($rhs).reset_spans();
12
13 assert_eq!(lhs, rhs);
14 }};
15}
16
17#[macro_export]
18macro_rules! b {
19 ($x:expr) => {
20 ::std::sync::Arc::new($crate::expr::Expr::Bool(
21 ::rexlang_lexer::span::Span::default(),
22 $x,
23 ))
24 };
25
26 ($span:expr; $x:expr) => {
27 ::std::sync::Arc::new($crate::expr::Expr::Bool(($span).into(), $x))
28 };
29
30 ($id:expr, $span:expr; $x:expr) => {
31 ::std::sync::Arc::new($crate::expr::Expr::Bool(($id).into(), ($span).into(), $x))
32 };
33}
34
35#[macro_export]
36macro_rules! u {
37 ($x:expr) => {
38 ::std::sync::Arc::new($crate::expr::Expr::Uint(
39 ::rexlang_lexer::span::Span::default(),
40 $x,
41 ))
42 };
43
44 ($span:expr; $x:expr) => {
45 ::std::sync::Arc::new($crate::expr::Expr::Uint(($span).into(), $x))
46 };
47
48 ($id:expr, $span:expr; $x:expr) => {
49 ::std::sync::Arc::new($crate::expr::Expr::Uint(($id).into(), ($span).into(), $x))
50 };
51}
52
53#[macro_export]
54macro_rules! i {
55 ($x:expr) => {
56 ::std::sync::Arc::new($crate::expr::Expr::Int(
57 ::rexlang_lexer::span::Span::default(),
58 $x,
59 ))
60 };
61
62 ($span:expr; $x:expr) => {
63 ::std::sync::Arc::new($crate::expr::Expr::Int(($span).into(), $x))
64 };
65
66 ($id:expr, $span:expr; $x:expr) => {
67 ::std::sync::Arc::new($crate::expr::Expr::Int(($id).into(), ($span).into(), $x))
68 };
69}
70
71#[macro_export]
72macro_rules! f {
73 ($x:expr) => {
74 ::std::sync::Arc::new($crate::expr::Expr::Float(
75 ::rexlang_lexer::span::Span::default(),
76 $x,
77 ))
78 };
79
80 ($span:expr; $x:expr) => {
81 ::std::sync::Arc::new($crate::expr::Expr::Float(($span).into(), $x))
82 };
83
84 ($id:expr, $span:expr; $x:expr) => {
85 ::std::sync::Arc::new($crate::expr::Expr::Float(($id).into(), ($span).into(), $x))
86 };
87}
88
89#[macro_export]
90macro_rules! s {
91 ($x:expr) => {
92 ::std::sync::Arc::new($crate::expr::Expr::String(
93 ::rexlang_lexer::span::Span::default(),
94 $x.to_string(),
95 ))
96 };
97
98 ($span:expr; $x:expr) => {
99 ::std::sync::Arc::new($crate::expr::Expr::String(($span).into(), ($x).to_string()))
100 };
101
102 ($id:expr, $span:expr; $x:expr) => {
103 ::std::sync::Arc::new($crate::expr::Expr::String(
104 ($id).into(),
105 ($span).into(),
106 ($x).to_string(),
107 ))
108 };
109}
110
111#[macro_export]
112macro_rules! tup {
113 ($($xs:expr),* $(,)?) => {
114 ::std::sync::Arc::new($crate::expr::Expr::Tuple(::rexlang_lexer::span::Span::default(), vec![$($xs),*]))
115 };
116
117 ($span:expr; $($xs:expr),* $(,)?) => {
118 ::std::sync::Arc::new($crate::expr::Expr::Tuple(($span).into(), vec![$($xs),*]))
119 };
120
121 ($id:expr, $span:expr; $($xs:expr),* $(,)?) => {
122 ::std::sync::Arc::new($crate::expr::Expr::Tuple(($id).into(), ($span).into(), vec![$($xs),*]))
123 };
124}
125
126#[macro_export]
127macro_rules! l {
128 ($($xs:expr),* $(,)?) => {
129 ::std::sync::Arc::new($crate::expr::Expr::List(::rexlang_lexer::span::Span::default(), vec![$($xs),*]))
130 };
131
132 ($span:expr; $($xs:expr),* $(,)?) => {
133 ::std::sync::Arc::new($crate::expr::Expr::List(($span).into(), vec![$($xs),*]))
134 };
135
136 ($id:expr, $span:expr; $($xs:expr),* $(,)?) => {
137 ::std::sync::Arc::new($crate::expr::Expr::List(($id).into(), ($span).into(), vec![$($xs),*]))
138 };
139}
140
141#[macro_export]
142macro_rules! d {
143 ($($k:ident = $v:expr),* $(,)?) => {
144 ::std::sync::Arc::new($crate::expr::Expr::Dict(::rexlang_lexer::span::Span::default(), {
145 let mut map = ::std::collections::BTreeMap::new();
146 $(map.insert($crate::expr::intern(stringify!($k)), $v);)*
147 map
148 }))
149 };
150
151 ($span:expr; $($k:ident = $v:expr),* $(,)?) => {
152 ::std::sync::Arc::new($crate::expr::Expr::Dict(($span).into(), {
153 let mut map = ::std::collections::BTreeMap::new();
154 $(map.insert($crate::expr::intern(stringify!($k)), $v);)*
155 map
156 }))
157 };
158
159 ($id:expr, $span:expr; $($k:ident = $v:expr),* $(,)?) => {
160 ::std::sync::Arc::new($crate::expr::Expr::Dict(($id).into(), ($span).into(), {
161 let mut map = ::std::collections::BTreeMap::new();
162 $(map.insert($crate::expr::intern(stringify!($k)), $v);)*
163 map
164 }))
165 };
166}
167
168#[macro_export]
169macro_rules! v {
170 ($x:expr) => {
171 ::std::sync::Arc::new($crate::expr::Expr::Var($crate::expr::Var {
172 span: ::rexlang_lexer::span::Span::default(),
173 name: $crate::expr::intern(&($x).to_string()),
174 }))
175 };
176
177 ($span:expr; $x:expr) => {
178 ::std::sync::Arc::new($crate::expr::Expr::Var($crate::expr::Var {
179 span: ($span).into(),
180 name: $crate::expr::intern(&($x).to_string()),
181 }))
182 };
183
184 ($id:expr, $span:expr; $x:expr) => {
185 ::std::sync::Arc::new($crate::expr::Expr::Var($crate::expr::Var {
186 id: ($id).into(),
187 span: ($span).into(),
188 name: $crate::expr::intern(&($x).to_string()),
189 }))
190 };
191}
192
193#[macro_export]
194macro_rules! app {
195 ($f:expr, $x:expr) => {
196 ::std::sync::Arc::new($crate::expr::Expr::App(
197 ::rexlang_lexer::span::Span::default(),
198 ($f).into(),
199 ($x).into(),
200 ))
201 };
202
203 ($span:expr; $f:expr, $x:expr) => {
204 ::std::sync::Arc::new($crate::expr::Expr::App(
205 ($span).into(),
206 ($f).into(),
207 ($x).into(),
208 ))
209 };
210
211 ($id:expr, $span:expr; $f:expr, $x:expr) => {
212 ::std::sync::Arc::new($crate::expr::Expr::App(
213 ($id).into(),
214 ($span).into(),
215 ($f).into(),
216 ($x).into(),
217 ))
218 };
219}
220
221#[macro_export]
222macro_rules! lam {
223 (λ $x:ident -> $e:expr) => {
224 ::std::sync::Arc::new($crate::expr::Expr::Lam(
225 ::rexlang_lexer::span::Span::default(),
226 $crate::expr::Scope::new_sync(),
227 $crate::expr::Var::new(stringify!($x)),
228 None,
229 Vec::new(),
230 ($e).into(),
231 ))
232 };
233
234 ($span:expr; λ $x:ident -> $e:expr) => {
235 ::std::sync::Arc::new($crate::expr::Expr::Lam(
236 ($span).into(),
237 $crate::expr::Scope::new_sync(),
238 $crate::expr::Var::new(stringify!($x)),
239 None,
240 Vec::new(),
241 ($e).into(),
242 ))
243 };
244
245 ($id:expr, $span:expr; λ $x:ident -> $e:expr) => {
246 ::std::sync::Arc::new($crate::expr::Expr::Lam(
247 ($id).into(),
248 ($span).into(),
249 $crate::expr::Scope::new_sync(),
250 $crate::expr::Var::new(stringify!($x)),
251 None,
252 Vec::new(),
253 ($e).into(),
254 ))
255 };
256}
257
258#[macro_export]
259macro_rules! let_in {
260 (let $x:ident = ($e1:expr) in $e2:expr) => {
261 ::std::sync::Arc::new($crate::expr::Expr::Let(
262 ::rexlang_lexer::span::Span::default(),
263 $crate::expr::Var::new(stringify!($x)),
264 None,
265 ($e1).into(),
266 ($e2).into(),
267 ))
268 };
269
270 ($span:expr; let $x:ident = ($e1:expr) in $e2:expr) => {
271 ::std::sync::Arc::new($crate::expr::Expr::Let(
272 ($span).into(),
273 $crate::expr::Var::new(stringify!($x)),
274 None,
275 ($e1).into(),
276 ($e2).into(),
277 ))
278 };
279
280 ($id:expr, $span:expr; let $x:ident = ($e1:expr) in $e2:expr) => {
281 ::std::sync::Arc::new($crate::expr::Expr::Let(
282 ($id).into(),
283 ($span).into(),
284 $crate::expr::Var::new(stringify!($x)),
285 None,
286 ($e1).into(),
287 ($e2).into(),
288 ))
289 };
290}
291
292#[macro_export]
293macro_rules! ite {
294 (if ($e1:expr) { $e2:expr } else { $e3:expr }) => {
295 ::std::sync::Arc::new($crate::expr::Expr::Ite(
296 ::rexlang_lexer::span::Span::default(),
297 ($e1).into(),
298 ($e2).into(),
299 ($e3).into(),
300 ))
301 };
302
303 ($span:expr; if ($e1:expr) { $e2:expr } else { $e3:expr }) => {
304 ::std::sync::Arc::new($crate::expr::Expr::Ite(
305 ($span).into(),
306 ($e1).into(),
307 ($e2).into(),
308 ($e3).into(),
309 ))
310 };
311
312 ($id:expr, $span:expr; if ($e1:expr) { $e2:expr } else { $e3:expr }) => {
313 ::std::sync::Arc::new($crate::expr::Expr::Ite(
314 ($span).into(),
315 ($e1).into(),
316 ($e2).into(),
317 ($e3).into(),
318 ))
319 };
320}