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
#![recursion_limit = "18446744073709551615"]
#![feature(trace_macros)]

trace_macros!(true);

// 每个mod都要有一个named宏,用于对结果命名,默认为ans
#[macro_export]
macro_rules! named {
    ( $any:tt ) => {
        #[macro_use]
        macro_rules! ans {
            ($var:ident)=>{
                $var!($any);
            };
            ($any1:tt $any2:tt) => {
                lambda!($any1 $any $any2);
            }
        }
    }
}

// 假如ab相同则执行一段代码

#[macro_export]
macro_rules! if_same_else {
    ([$($a:tt)*] [$($b:tt)*] [$($any0:tt)*] [$($any1:tt)*]) => {
        #[macro_use]
        macro_rules! if_a_same_as_b_else {
            ($($b)* ) => {
                lambda!($($any0)*);
            };
            ( $($a)*) => {
                lambda!($($any1)*);
            };
        }
        if_a_same_as_b_else!($($a)*);
    };
}


// 主宏
#[macro_export]
macro_rules! lambda {

    // 假如开头有赋值语句,进行赋值操作
    // 创建同名模块并创建导出同名宏
    ($var:ident = $($any:tt)*)=>{
        mod $var{
            use super::*;
            #[macro_use]
            macro_rules! named {
                ( $any1:tt ) => {
                    #[macro_export]
                    macro_rules! $var {
                        ($var1:ident)=>{
                            $var1!($any1);
                        };
                        ($any2:tt $any3:tt) => {
                            lambda!($any2 $any1 $any3);
                        };
                    }
                };
            }
            lambda!($($any)*);
        }
    };

    // 去除开头的无变量的大括号
    ({$($any0:tt)*})=>{
        lambda!($($any0)*);
    };

    ({$($any0:tt)*},$($any1:tt)*)=>{
        lambda!($($any0)*, $($any1)* );
    };

    // 去除中括号
    ([$($any0:tt)*] [$($any1:tt)*] [$($any2:tt)*]) => {
        lambda!($($any0)* $($any1)* $($any2)*);
    };

    // 处理可被化简的小括号
    //  1.小括号在开头
    (($($any1:tt)*) $($any2:tt)*)=>{
        lambda!($($any1:tt)* $($any2:tt)*);
    };

    //  2.小括号在第二位
    ( $fun:tt $($var:ident)* , ( $($any1:tt)*) $($any2:tt)*  )=> {
        lambda!( $($any1)*; $fun $($var)*, _ $($any2)*);
    };

    // 假如变量是标识符,那么它一定是一个宏,中括号用于把所有的变为一个变量
    //  标识符在第一位
    ($var:ident $($any:tt)*)=>{
        $var!([] [$($any)*]  );
    };

    //  标识符在第二位
    ($fun0:tt $($var0:ident)* , $var:ident $($any:tt)*)=> {
        $var!([$fun0 $($var0)* ,] [$($any)*]  );
    };

    // 假如输入的变量为无参数的大括号
    ({[$($any0:tt)*] $($any1:tt)* } $($var0:ident)* , {$($any2:tt)*} $( , $fun2:tt $($var2:ident)* )*  $(; $( $fun3:tt $($var3:ident)*),*)*  )=>{
        lambda!({[$($any0)* ,($($any2)*) ] $($any1)* } $($var0)* $( , $fun2 $($var2)* )*  $(; $( $fun3 $($var3)*),*)*);
    };

    // 替换结束
    ({[,$($any0:tt)*]} $var00:ident $($var01:ident)*, $fun1:tt $($var1:ident)* $( , $fun2:tt $($var2:ident)* )*  $(; $( $fun3:tt $($var3:ident)*),*)*  )=>{
        lambda!( {$($any0)*} $($var01)* $( , $fun2 $($var2)* )*  $(; $( $fun3 $($var3)*),*)* );
    };

    // 替换到小括号
    ({[$($any0:tt)*], ($($any1:tt)*) $($any2:tt)* } $var00:ident $($var01:ident)* , $fun1:tt $($var1:ident)*  $( , $fun2:tt $($var2:ident)* )*  $(; $( $fun3:tt $($var3:ident)*),*)* )=>{
        lambda!({[$($any0)*] $($any2)* }  $var00 $($var01)* , ({$($any1)*} $var00 ,  $fun1 $($var1)*) , $fun1 $($var1)* $( , $fun2 $($var2)* )*  $(; $( $fun3 $($var3)*),*)*);
    };

    // 假如输入的变量为有参数的函数体
    ({[$($any0:tt)*], $fun1:tt $($var1:ident)* $( , $fun11:tt $($var11:ident)* )*  } $var00:ident $($var01:ident)* , $fun2:tt $($var2:ident)*  $( , $fun3:tt $($var3:ident)* )*  $(; $( $fun4:tt $($var4:ident)*),*)*  )=>{
        if_same_else!(
            [$fun1 $($var1)*] [$var00][
                {[$($any0)*, $fun2 $($var2)*] $( , $fun11 $($var11)* )* } $var00 $($var01)* , $fun2 $($var2)*  $( , $fun3 $($var3)* )*  $(; $( $fun4 $($var4)*),*)*
            ] [
                {[$($any0)*, $fun1 $($var1)*] $( , $fun11 $($var11)* )* } $var00 $($var01)* , $fun2 $($var2)*  $( , $fun3 $($var3)* )*  $(; $( $fun4 $($var4)*),*)*
            ]
        );
    };


    // 开始替换
    ({$($any0:tt)*}$($var0:ident)* , $fun1:tt $($var1:ident)*  $( , $fun2:tt $($var2:ident)* )*  $(; $( $fun3:tt $($var3:ident)*),*)*  )=> {
        lambda!({[] , $($any0)*} $($var0)* , $fun1 $($var1)*   $( , $fun2 $($var2)* )*  $(; $( $fun3 $($var3)*),*)*);
    };


    // 处理分号
    ( $fun1:tt $($var1:ident)* ;  $fun2:tt $($var2:ident)* , _ $($any:tt)*  )=>{
        lambda!( $fun2 $($var2)* , $fun1 $($var1)* $($any)*);
    };

    //处理不了的其他情况,用named宏对其命名
    // ans接受一个宏的名称
    ($($any:tt)*)=>{
        named!([$($any)*]);
    };


}


#[macro_use]
mod into;

#[macro_use]
mod math;

lambda!(add1 = {f, (n , f , x) }n f x );
lambda!(add = {a , add1 , b} add1 a b , add1);

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn it_works() {
        trace_macros!(true);
        println!("{}",lambda!(to_str, add1 ,one));
        println!("{}",lambda!(to_str, add , one , zero));
        println!("{}",lambda!(to_str, add1 , (add , one , zero)));
    }
}