1
2#[macro_export]
11macro_rules! sexpr {
12 { $(;)? } => {
14 $crate::HNil
15 };
16
17
18 { ; { $($head:tt)* } } => {
20 $crate::sexpr!{ $($head)* }
21 };
22
23 { ; @ {$($head:tt)*} $(= $val:expr)? } => {
24 $crate::Quote< $crate::sexpr!{ $($head)* } >
25 };
26
27 { ; @ $head:ty $(= $val:expr)? } => {
28 $crate::Quote< $head >
29 };
30
31 { ; $head:ty } => { $head };
32
33
34 { { $($head:tt)* } ; $($tail:tt)+ } => {
36 $crate::HCons< $crate::sexpr!{$($head)*},
37 $crate::sexpr!{;$($tail)*} >
38 };
39
40 { @ {$($head:tt)*} $(= $val:expr)? ; $($tail:tt)+ } => {
41 $crate::HCons< $crate::Quote< $crate::sexpr!{$($head)*}>,
42 $crate::sexpr!{;$($tail)*} >
43 };
44
45 { @ $head:ty $(= $val:expr)?; $($tail:tt)+ } => {
46 $crate::HCons< $crate::Quote< $head >,
47 $crate::sexpr!{;$($tail)*} >
48 };
49
50 { $head:ty ; $($tail:tt)+ } => {
51 $crate::HCons< $head,
52 $crate::sexpr!{;$($tail)*} >
53 };
54
55
56 { { $($head:tt)* } $(, $($tail:tt)*)? } => {
58 $crate::HCons< $crate::sexpr!{$($head)*},
59 $crate::sexpr!{$($($tail)*)?} >
60 };
61
62 { @ {$($head:tt)*} $(= $val:expr)? $(, $($tail:tt)*)? } => {
63 $crate::HCons< $crate::Quote< $crate::sexpr!{ $($head)* } >,
64 $crate::sexpr!{$($($tail)*)?} >
65 };
66
67 { @ $head:ty $(= $val:expr)? $(, $($tail:tt)*)? } => {
68 $crate::HCons< $crate::Quote< $head >,
69 $crate::sexpr!{$($($tail)*)?} >
70 };
71
72 { $head:ty $(, $($tail:tt)*)? } => {
73 $crate::HCons< $head,
74 $crate::sexpr!{$($($tail)*)?} >
75 };
76}
77
78#[macro_export]
79macro_rules! sexpr_quoted_types {
80 { $(;)? } => {
82 $crate::HNil
83 };
84
85
86 { ; { $($head:tt)* } } => { () };
88 { ; @ {$($head:tt)*}=$val:expr } => {
89 $crate::sexpr!{$($head:tt)*} = $val
90 };
91 { ; @ {$($head:tt)*} } => { () };
92 { ; @ $head:ty=$val:expr } => {
93 $head = $val
94 };
95 { ; @ $head:ty } => { () };
96 { ; $head:ty } => { () };
97
98
99 { { $($head:tt)* } ; $($tail:tt)+ } => {
101 $crate::HCons < $crate::sexpr_quoted_types!{$($head)*},
102 $crate::sexpr_quoted_types!{;$($tail)*} >
103 };
104
105 { @ {$($head:tt)*} = $val:expr ; $($tail:tt)+ } => {
106 $crate::HCons < $crate::sexpr!{$($head:tt)*},
107 $crate::sexpr_quoted_types!{;$($tail)*} >
108 };
109 { @ {$($head:tt)*} ; $($tail:tt)+ } => {
110 $crate::HCons < (),
111 $crate::sexpr_quoted_types!{;$($tail)*} >
112 };
113
114 { @ $head:ty = $val:expr; $($tail:tt)+ } => {
115 $crate::HCons< $head,
116 $crate::sexpr_quoted_types!{;$($tail)*} >
117 };
118 { @ $head:ty; $($tail:tt)+ } => {
119 $crate::HCons< (),
120 $crate::sexpr_quoted_types!{;$($tail)*} >
121 };
122
123 { $head:ty ; $($tail:tt)+ } => {
124 $crate::HCons< (),
125 $crate::sexpr_quoted_types!{;$($tail)*} >
126 };
127
128
129 { { $($head:tt)* } $(, $($tail:tt)*)? } => {
131 $crate::HCons< $crate::sexpr_quoted_types!{$($head)*},
132 $crate::sexpr_quoted_types!{$($($tail)*)?} >
133 };
134
135 { @ {$($head:tt)*} = $val:expr $(, $($tail:tt)*)? } => {
136 $crate::HCons< $crate::sexpr!{$($head:tt)*},
137 $crate::sexpr_quoted_types!{$($($tail)*)?} >
138 };
139
140 { @ {$($head:tt)*} $(, $($tail:tt)*)? } => {
141 $crate::HCons< (),
142 $crate::sexpr_quoted_types!{$($($tail)*)?} >
143 };
144
145 { @ $head:ty = $val:expr $(, $($tail:tt)*)? } => {
146 $crate::HCons< $head,
147 $crate::sexpr_quoted_types!{$($($tail)*)?} >
148 };
149
150 { @ $head:ty $(, $($tail:tt)*)? } => {
151 $crate::HCons< (),
152 $crate::sexpr_quoted_types!{$($($tail)*)?} >
153 };
154
155 { $head:ty $(, $($tail:tt)*)? } => {
156 $crate::HCons< (),
157 $crate::sexpr_quoted_types!{$($($tail)*)?} >
158 };
159}
160
161
162#[macro_export]
164macro_rules! sexpr_quoted_vals {
165 { $(;)? } => {
167 $crate::HNil
168 };
169
170
171 { ; { $($head:tt)* } } => { () };
173 { ; @ {$($head:tt)*}=$val:expr } => {
174 {let _x:$crate::sexpr!{$($head:tt)*} = $val; _x}
175 };
176 { ; @ {$($head:tt)*} } => { () };
177 { ; @ $head:ty=$val:expr } => {
178 {let _x:$head = $val; _x}
179 };
180 { ; @ $head:ty } => { () };
181 { ; $head:ty } => { () };
182
183
184 { { $($head:tt)* } ; $($tail:tt)+ } => {
186 $crate::HCons { head : $crate::sexpr_quoted_vals!{$($head)*},
187 tail : $crate::sexpr_quoted_vals!{;$($tail)*} }
188 };
189
190 { @ {$($head:tt)*} = $val:expr ; $($tail:tt)+ } => {
191 $crate::HCons { head : {let _x:$crate::sexpr!{$($head:tt)*} = $val; _x},
192 tail : $crate::sexpr_quoted_vals!{;$($tail)*} }
193 };
194 { @ {$($head:tt)*} ; $($tail:tt)+ } => {
195 $crate::HCons { head: (),
196 tail: $crate::sexpr_quoted_vals!{;$($tail)*} }
197 };
198
199 { @ $head:ty = $val:expr; $($tail:tt)+ } => {
200 $crate::HCons{ head: {let _x:$head = $val; _x},
201 tail: $crate::sexpr_quoted_vals!{;$($tail)*} }
202 };
203 { @ $head:ty; $($tail:tt)+ } => {
204 $crate::HCons{ head: (),
205 tail: $crate::sexpr_quoted_vals!{;$($tail)*} }
206 };
207
208 { $head:ty ; $($tail:tt)+ } => {
209 $crate::HCons{ head: (),
210 tail: $crate::sexpr_quoted_vals!{;$($tail)*} }
211 };
212
213
214 { { $($head:tt)* } $(, $($tail:tt)*)? } => {
216 $crate::HCons{ head: $crate::sexpr_quoted_vals!{$($head)*},
217 tail: $crate::sexpr_quoted_vals!{$($($tail)*)?} }
218 };
219
220 { @ {$($head:tt)*} = $val:expr $(, $($tail:tt)*)? } => {
221 $crate::HCons{ head: {let _x:$crate::sexpr!{$($head:tt)*} = $val; _x},
222 tail: $crate::sexpr_quoted_vals!{$($($tail)*)?} }
223 };
224
225 { @ {$($head:tt)*} $(, $($tail:tt)*)? } => {
226 $crate::HCons{ head: (),
227 tail: $crate::sexpr_quoted_vals!{$($($tail)*)?} }
228 };
229
230 { @ $head:ty = $val:expr $(, $($tail:tt)*)? } => {
231 $crate::HCons{ head: {let _x:$head = $val; _x},
232 tail: $crate::sexpr_quoted_vals!{$($($tail)*)?} }
233 };
234
235 { @ $head:ty $(, $($tail:tt)*)? } => {
236 $crate::HCons{ head: (),
237 tail: $crate::sexpr_quoted_vals!{$($($tail)*)?} }
238 };
239
240 { $head:ty $(, $($tail:tt)*)? } => {
241 $crate::HCons{ head: (),
242 tail: $crate::sexpr_quoted_vals!{$($($tail)*)?} }
243 };
244}
245
246#[macro_export]
248macro_rules! sexpr_val {
249 { $(;)? } => {
251 $crate::HNil
252 };
253
254 { ; @{ $($head:tt)* } } => { $crate::sexpr_val!{$($head)*} };
256 { ; $head:expr } => { $head };
257
258 { @{ $($head:tt)* } ; $($tail:tt)* } => {
259 $crate::HCons{ head: $crate::sexpr_val!{$($head)*},
260 tail: $crate::sexpr_val!{;$($tail)*} }
261 };
262 { $head:expr ; $($tail:tt)* } => {
263 $crate::HCons{ head: $head,
264 tail: $crate::sexpr_val!{;$($tail)*} }
265 };
266
267 { @{ $($head:tt)* } $(, $($tail:tt)*)? } => {
268 $crate::HCons{ head: $crate::sexpr_val!{$($head)*},
269 tail: $crate::sexpr_val!{$($($tail)*)?} }
270 };
271 { $head:expr $(, $($tail:tt)*)? } => {
272 $crate::HCons{ head: $head,
273 tail: $crate::sexpr_val!{$($($tail)*)?} }
274 };
275}
276
277
278#[macro_export]
280macro_rules! sexpr_pat_ty {
281 { $(;)? } => {
283 $crate::HNil
284 };
285
286 { ; { $($head:tt)* } } => { $crate::sexpr_pat_ty!{$($head)*} };
288 { ; $head:tt : $ty:ty } => { $ty };
289
290 { { $($head:tt)* } ; $($tail:tt)* } => {
291 $crate::HCons< $crate::sexpr_pat_ty!{$($head)*},
292 $crate::sexpr_pat_ty!{;$($tail)*} >
293 };
294 { $head:tt : $ty:ty; $($tail:tt)* } => {
295 $crate::HCons< $ty,
296 $crate::sexpr_pat_ty!{;$($tail)*} >
297 };
298
299 { { $($head:tt)* } $(, $($tail:tt)*)? } => {
300 $crate::HCons< $crate::sexpr_pat_ty!{$($head)*},
301 $crate::sexpr_pat_ty!{$($($tail)*)?} >
302 };
303 { $head:tt : $ty:ty $(, $($tail:tt)*)? } => {
304 $crate::HCons< $ty,
305 $crate::sexpr_pat_ty!{$($($tail)*)?} >
306 };
307}
308
309#[macro_export]
311macro_rules! sexpr_pat {
312 { $(;)? } => {
314 $crate::HNil
315 };
316
317 { ; { $($head:tt)* } } => { $crate::sexpr_pat!{$($head)*} };
319 { ; $head:tt : $ty:ty } => { $head };
320
321 { { $($head:tt)* } ; $($tail:tt)* } => {
322 $crate::HCons{ head: $crate::sexpr_pat!{$($head)*},
323 tail: $crate::sexpr_pat!{;$($tail)*} }
324 };
325 { $head:tt : $ty:ty; $($tail:tt)* } => {
326 $crate::HCons{ head: $head,
327 tail: $crate::sexpr_pat!{;$($tail)*} }
328 };
329
330 { { $($head:tt)* } $(, $($tail:tt)*)? } => {
331 $crate::HCons{ head: $crate::sexpr_pat!{$($head)*},
332 tail: $crate::sexpr_pat!{$($($tail)*)?} }
333 };
334 { $head:tt : $ty:ty $(, $($tail:tt)*)? } => {
335 $crate::HCons{ head: $head,
336 tail: $crate::sexpr_pat!{$($($tail)*)?} }
337 };
338}
339
340#[macro_export]
342macro_rules! eval { ($($expr:tt)*) => { <$crate::sexpr!{$($expr)*} as $crate::engine::Eval>::Result } }
343
344#[macro_export]
345macro_rules! partial { ($($expr:tt)*) => { $crate::ops::PartialImpl<$crate::sexpr!{$($expr)*}> }}
346
347#[macro_export]
348macro_rules! calc { ($($expr:tt)*) => {
349 $crate::engine::calc::<$crate::sexpr!{$($expr)*}, $crate::sexpr_quoted_types!{$($expr)*}>(
350 $crate::sexpr_quoted_vals!{$($expr)*}
351 )
352}}
353
354#[macro_export]
355macro_rules! calc_ty { ($($expr:tt)*) => {
356 <$crate::sexpr!{$($expr)*} as $crate::engine::Calc<$crate::sexpr_quoted_types!{$($expr)*}>>::Result
357}}
358
359#[macro_export]
360macro_rules! calc_bound { ($($expr:tt)*) => {
361 $crate::engine::Calc<$crate::sexpr_quoted_types!{$($expr)*}>
362}}
363
364#[macro_export]
366macro_rules! literal {
367 { $(
368 $({$($gen:tt)*})? $ty:ty
369 );+ } => { $(
370 impl$(<$($gen)*>)? $crate::engine::Eval for $ty { type Result = Self; }
371 impl<Q,$($($gen)*)?> $crate::engine::Calc<Q> for $ty where Self: ::std::default::Default {
372 type Result = Self;
373 #[inline(always)]
374 fn calc(_:Q)->Self { ::std::default::Default::default() }
375 }
376 impl$(<$($gen)*>)? $crate::LispId for $ty { type Id = $crate::uuid_new_v4!(| $crate::typenum); }
377 )* }
378}
379
380#[cfg(feature="const")]
381#[macro_export]
382macro_rules! literal_with_id {
383 { $(
384 $({$($gen:tt)*})? $ty:ty : $id:literal
385 );+ } => { $(
386 impl$(<$($gen)*>)? $crate::engine::Eval for $ty { type Result = Self; }
387 impl<Q,$($($gen)*)?> $crate::engine::Calc<Q> for $ty where Self: ::std::default::Default {
388 type Result = Self;
389 #[inline(always)]
390 fn calc(_:Q)->Self { ::std::default::Default::default() }
391 }
392 impl$(<$($gen)*>)? $crate::LispId for $ty {
393 type Id = $crate::ConstId<$id>;
394 }
395 )* }
396}
397
398#[macro_export]
399macro_rules! non_calc_literal {
400 { $(
401 $({$($gen:tt)*})? $ty:ty
402 );+ } => { $(
403 impl$(<$($gen)+>)? $crate::engine::Eval for $ty { type Result = Self; }
404 impl$(<$($gen)+>)? $crate::LispId for $ty { type Id = $crate::uuid_new_v4!(| $crate::typenum); }
405 )* }
406}
407
408#[macro_export]
418macro_rules! defun {
419 {$id:ty { $($body:tt)* }} => {$crate::defun!{@self () $id { $($body)* }}};
420 {@$self: tt ($($id_gen:tt)*) $id:ty { $(
421 ($($generics:tt)*) $(calc where ($($calcbound:tt)*))? { $($args:tt)* } $({$($preamble:stmt;)*})? => { $($out:tt)* };
422 )* }} => {
423 $crate::defun_nocalc!{($($id_gen)*) $id {$(
424 ( $($generics)* ) { $($args)* } => { $($out)* };
425 )*}}
426 $(
427 impl<$($generics)*> $crate::engine::FunCalc< $crate::sexpr_pat_ty!{$($args)*} > for $id
428 where
429 $crate::sexpr!{$($out)*}: $crate::engine::Calc< $crate::sexpr_quoted_types!{$($out)*} >,
431 $($($calcbound)*)?
432 {
433 type Result = <$crate::sexpr!{ $($out)* } as $crate::engine::Calc< $crate::sexpr_quoted_types!{$($out)*} >>::Result;
434 #[inline(always)]
435 fn calc($self, args: $crate::sexpr_pat_ty!{$($args)*})
436 -> Self::Result {
437 #[allow(redundant_semicolons)]
438 let syntax: $crate::sexpr_quoted_types!{$($out)*} = {
439 let $crate::sexpr_pat!{$($args)*}: $crate::sexpr_pat_ty!{$($args)*} = args;
440 $($($preamble;)*)?
441 $crate::sexpr_quoted_vals!{$($out)*}
442 };
443 <$crate::sexpr!{$($out)*} as $crate::engine::Calc< $crate::sexpr_quoted_types!{$($out)*} >>::calc(syntax)
444 }
445 }
446 )*
447 }
448}
449
450pub trait Everything {}
454impl<T:?Sized> Everything for T {}
455
456#[macro_export]
457macro_rules! defun_rust {
458 ( ($($header:tt)+) -> {$($expr:tt)*} $((as $($res_bound:tt)+))? $(where $($bound:tt)+)? ) => {
459 $($header)+ -> <$crate::sexpr!{ $($expr)* } as $crate::engine::Calc< $crate::sexpr_quoted_types!{$($expr)*} >>::Result
460 where $crate::sexpr!{$($expr)*}: $crate::engine::Calc< $crate::sexpr_quoted_types!{$($expr)*} >,
461 <$crate::sexpr!{ $($expr)* } as $crate::engine::Calc< $crate::sexpr_quoted_types!{$($expr)*} >>::Result: $crate::macros::Everything + $($($res_bound)+,)?
462 $( $($bound)+)?
463 {
464 let syntax: $crate::sexpr_quoted_types!{$($expr)*} = $crate::sexpr_quoted_vals!{$($expr)*};
465 <$crate::sexpr!{$($expr)*} as $crate::engine::Calc< $crate::sexpr_quoted_types!{$($expr)*} >>::calc(syntax)
466 }
467 }
468}
469
470#[macro_export]
471macro_rules! defun_nocalc {
472 {($($id_gen:tt)*) $id:ty { $(
473 ($($generics:tt)*) { $($args:tt)* } $(where ($($bound:tt)+))? => { $($out:tt)* };
474 )* }} => {
475 $crate::literal!{{$($id_gen)*} $id}
476 impl<$($id_gen)*> $crate::engine::Call for $id { type Conv=$crate::engine::cc::Func; }
477 $(
478 impl<$($generics)*> $crate::engine::FunCall< $crate::sexpr_pat_ty!{$($args)*} > for $id
479 where $crate::sexpr!{$($out)*}: $crate::engine::Eval $(,$($bound)+)? {
480 type Result = $crate::eval!{ $($out)* };
481 }
482 )*
483 }
484}
485
486#[macro_export]
493macro_rules! defmacro {
494 {$id:ty { $(
495 ($($generics:tt)*) { $($args:tt)* } => { $($out:tt)* };
496 )* }} => {
497 $crate::literal!{$id}
498 impl $crate::engine::Call for $id { type Conv=$crate::engine::cc::Syntax; }
499 $(
500 impl<$($generics)*> $crate::engine::SynCall< sexpr!{$($args)*} > for $id
501 where $crate::sexpr!{$($out)*}: $crate::engine::Eval {
502 type Result = $crate::eval!{ $($out)* };
503 }
504 )*
505 }
506}
507
508#[cfg(test)]
509macro_rules! assert_type_eq {
510 ($a:ty, $b:ty) => { let _: ::core::marker::PhantomData<$a>=
511 <::core::marker::PhantomData<$b> as ::core::default::Default>::default();
512 }
513}
514