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
use TokenStream;
use ;
/// Manipulates a macro_rules! definition to add extended syntax to help in creating readable macros.
///
/// # Usage
///
/// CPS macros are a strict superset of Rust macro-rules. This means that any (\*) regular rust macro can
/// be prefaced by `#[cps]` and behave exactly the same.
///
/// The added syntax is the new `let` bindings allowed before the body of macro rules. These let statements
/// allow other `cps` macros to be evaluated *before* the body is evaluated. Let bindings are executed in order,
/// and can refer to the results of previous let binding results.
///
/// \* You may not begin a rule with the tokens `@_cps`
///
/// ## Evaluation Order
///
/// ```
/// # use cps::cps;
/// #[cps]
/// macro_rules! macro1 {
/// (a) => {
/// CaseA
/// };
/// (b) => {
/// CaseB
/// };
/// (CaseA) => {
/// MatchedCaseA
/// };
/// }
///
/// #[cps]
/// macro_rules! macro2 {
/// (a_b) =>
/// let $x:tt = macro1!(a) in
/// let $x2:tt = cps::stringify!($x) in
/// let $y:tt = macro1!(b) in
/// let $y2:tt = cps::stringify!($y) in
/// {
/// concat!($x2, $y2)
/// };
///
/// (sequential) =>
/// let $x:tt = macro1!(a) in
/// let $y:tt = macro1!($x) in
/// {
/// stringify!($y)
/// };
/// }
///
/// fn main() {
/// assert_eq!(macro2!(a_b), "CaseACaseB");
/// assert_eq!(macro2!(sequential), "MatchedCaseA");
/// }
/// ```
///
/// ## Macro indirection
///
/// The result of a previous let binding can be used as the name of a later let binding:
///
/// ```
/// # use cps::cps;
/// #[cps]
/// macro_rules! input_macro1 {
/// (next) => {
/// input_macro2
/// };
/// }
///
/// #[cps]
/// macro_rules! input_macro2 {
/// () => {
/// BaseCase2
/// };
/// }
///
/// #[cps]
/// macro_rules! macro1 {
/// ($cont1:ident) =>
/// let $cont2:ident = $cont1!(next) in
/// let $x:tt = $cont2!() in // Invoke the result of `$cont1!(next)`
/// {
/// stringify!($x)
/// };
/// }
///
/// fn main() {
/// assert_eq!(macro1!(input_macro1), "BaseCase2");
/// }
/// ```
///
/// [tlborm]: https://veykril.github.io/tlborm/decl-macros/patterns/callbacks.html
export_std_cps!;
export_std_cps!;
export_std_cps!;
export_std_cps!;