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
use *;
/// `macro_loop!` provides special fragment features using `@`.
///
/// # For Loops
///
/// Syntax: `@for <item> in <values> { ... }`
///
/// For loops emit their body per value:
///
/// ```rust
/// macro_loop! {
/// @for N in 2..=4 {
/// struct @[Vec @N];
/// }
/// }
///
/// // outputs:
/// // struct Vec2;
/// // struct Vec3;
/// // struct Vec4;
/// ```
///
/// The `<item>` needs to be a ***pattern*** - Either:
/// * an identifier (`Prime`),
/// * an array of patterns (`[CapeLight, [Sprinter, Truth]]`).
///
/// The `<values>` needs to be an array value that matches the `<item>` pattern.
/// A values is either:
/// * a literal,
/// * an identifier,
/// * an array of values.
///
/// Values support operators such as `+`, `..` and `==`.
///
/// Declaring a for loop with multiple parameters (`@for a in [...], b in [...]`),
/// emits the body per value combination.
///
/// # If Statements
///
/// Syntax: `@if <condition> { ... }`
///
/// An if statement emits its body only if its condition is met:
///
/// ```rust
/// macro_rules! not_equal {
/// ($a:ident $b:ident) => {
/// macro_loop! {
/// @if $a != $b {
/// println!("{}", stringify!($a != $b))
/// }
/// }
/// };
/// }
///
/// fn main() {
/// not_equal!(a a); // doesn't print
/// not_equal!(a b); // prints
/// not_equal!(b b); // doesn't print
/// }
/// ```
///
/// The `<condition>` needs to be a bool value.
///
/// # Let Statements
///
/// Syntax: `@let <name> = <value>;`
///
/// Let statements declare names that have a value:
///
/// macro_loop! {
/// @let components = [x, y, z, w];
///
/// @for X in @components, Y in @components] {
/// ...
/// }
/// }
///
/// The `<name>` needs to be a pattern, and the ~value~ has to match it.
///
/// # Identifiers
///
/// Syntax: `@[<idents>]`
///
/// Concats identifier segments into a single identifier:
///
/// ```rust
/// @let N = 5;
///
/// struct @[Struct @N]; // Struct5
/// ```