competitive/tools/
mlambda.rs1#[macro_export]
26macro_rules! mlambda {
27 (
28 @def ($dol:tt) [$([$x:ident])*][$([$y:ident, $($z:tt)*])*]
29 fn $name:ident($($args:tt)*) -> $ret:ty $body:block
30 ) => {
31 macro_rules! $name {
32 ($($dol $x:expr),* $dol(,)?) => {{
33 $(let $y $($z)* = $dol $y;)*
34 $body
35 }}
36 }
37 };
38 (@pre () [$($x:tt)*][$($y:tt)*] fn $name:ident($($args:tt)*) -> $ret:ty $body:block) => {
39 $crate::mlambda!(@def ($) [$($x)*][$($y)*] fn $name($($args)*) -> $ret $body)
40 };
41 (@pre () [$($x:tt)*][$($y:tt)*] fn $name:ident($($args:tt)*) $body:block) => {
42 $crate::mlambda!(@pre () [$($x)*][$($y)*] fn $name($($args)*) -> () $body)
43 };
44 (@pre ($arg:ident $(:$ty:ty)?) [$($x:tt)*][$($y:tt)*] $($rest:tt)*) => {
45 $crate::mlambda!(@pre () [$($x)* [$arg]][$($y)* [$arg, $(:$ty)?]] $($rest)*)
46 };
47 (@pre ($arg:ident $(:$ty:ty)?, $($args:tt)*) [$($x:tt)*][$($y:tt)*] $($rest:tt)*) => {
48 $crate::mlambda!(@pre ($($args)*) [$($x)* [$arg]][$($y)* [$arg, $(:$ty)?]] $($rest)*)
49 };
50 (fn $name:ident($($args:tt)*) $($rest:tt)*) => {
51 $crate::mlambda!(@pre ($($args)*) [][] fn $name($($args)*) $($rest)*)
52 };
53}