@@ -11,7 +11,7 @@ which both pattern-match on their input and both return early in one case,
1111doing nothing otherwise:
1212
1313~~~~
14- # enum T { SpecialA(uint), SpecialB(uint) };
14+ # enum T { SpecialA(uint), SpecialB(uint) }
1515# fn f() -> uint {
1616# let input_1 = SpecialA(0);
1717# let input_2 = SpecialA(0);
@@ -37,7 +37,8 @@ lightweight custom syntax extensions, themselves defined using the
3737the pattern in the above code:
3838
3939~~~~
40- # enum T { SpecialA(uint), SpecialB(uint) };
40+ # #![feature(macro_rules)]
41+ # enum T { SpecialA(uint), SpecialB(uint) }
4142# fn f() -> uint {
4243# let input_1 = SpecialA(0);
4344# let input_2 = SpecialA(0);
@@ -55,6 +56,7 @@ early_return!(input_1 SpecialA);
5556early_return!(input_2 SpecialB);
5657# return 0;
5758# }
59+ # fn main() {}
5860~~~~
5961
6062Macros are defined in pattern-matching style: in the above example, the text
@@ -155,7 +157,8 @@ separator token (a comma-separated list could be written `$(...),*`), and `+`
155157instead of ` * ` to mean "at least one".
156158
157159~~~~
158- # enum T { SpecialA(uint),SpecialB(uint),SpecialC(uint),SpecialD(uint)};
160+ # #![feature(macro_rules)]
161+ # enum T { SpecialA(uint),SpecialB(uint),SpecialC(uint),SpecialD(uint)}
159162# fn f() -> uint {
160163# let input_1 = SpecialA(0);
161164# let input_2 = SpecialA(0);
@@ -175,6 +178,7 @@ early_return!(input_1, [SpecialA|SpecialC|SpecialD]);
175178early_return!(input_2, [SpecialB]);
176179# return 0;
177180# }
181+ # fn main() {}
178182~~~~
179183
180184### Transcription
@@ -215,9 +219,10 @@ solves the problem.
215219Now consider code like the following:
216220
217221~~~~
218- # enum T1 { Good1(T2, uint), Bad1};
222+ # #![feature(macro_rules)]
223+ # enum T1 { Good1(T2, uint), Bad1}
219224# struct T2 { body: T3 }
220- # enum T3 { Good2(uint), Bad2};
225+ # enum T3 { Good2(uint), Bad2}
221226# fn f(x: T1) -> uint {
222227match x {
223228 Good1(g1, val) => {
@@ -232,6 +237,7 @@ match x {
232237 _ => return 0 // default value
233238}
234239# }
240+ # fn main() {}
235241~~~~
236242
237243All the complicated stuff is deeply indented, and the error-handling code is
@@ -240,6 +246,7 @@ a match, but with a syntax that suits the problem better. The following macro
240246can solve the problem:
241247
242248~~~~
249+ # #![feature(macro_rules)]
243250macro_rules! biased_match (
244251 // special case: `let (x) = ...` is illegal, so use `let x = ...` instead
245252 ( ($e:expr) ~ ($p:pat) else $err:stmt ;
@@ -261,9 +268,9 @@ macro_rules! biased_match (
261268 )
262269)
263270
264- # enum T1 { Good1(T2, uint), Bad1};
271+ # enum T1 { Good1(T2, uint), Bad1}
265272# struct T2 { body: T3 }
266- # enum T3 { Good2(uint), Bad2};
273+ # enum T3 { Good2(uint), Bad2}
267274# fn f(x: T1) -> uint {
268275biased_match!((x) ~ (Good1(g1, val)) else { return 0 };
269276 binds g1, val )
@@ -273,13 +280,16 @@ biased_match!((g1.body) ~ (Good2(result) )
273280// complicated stuff goes here
274281return result + val;
275282# }
283+ # fn main() {}
276284~~~~
277285
278286This solves the indentation problem. But if we have a lot of chained matches
279287like this, we might prefer to write a single macro invocation. The input
280288pattern we want is clear:
281289
282290~~~~
291+ # #![feature(macro_rules)]
292+ # fn main() {}
283293# macro_rules! b(
284294 ( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*
285295 binds $( $bind_res:ident ),*
@@ -301,14 +311,18 @@ process the semicolon-terminated lines, one-by-one. So, we want the following
301311input patterns:
302312
303313~~~~
314+ # #![feature(macro_rules)]
304315# macro_rules! b(
305316 ( binds $( $bind_res:ident ),* )
306317# => (0))
318+ # fn main() {}
307319~~~~
308320
309321...and:
310322
311323~~~~
324+ # #![feature(macro_rules)]
325+ # fn main() {}
312326# macro_rules! b(
313327 ( ($e :expr) ~ ($p :pat) else $err :stmt ;
314328 $( ($e_rest:expr) ~ ($p_rest:pat) else $err_rest:stmt ; )*
@@ -322,6 +336,8 @@ The resulting macro looks like this. Note that the separation into
322336piece of syntax (the ` let ` ) which we only want to transcribe once.
323337
324338~~~~
339+ # #![feature(macro_rules)]
340+ # fn main() {
325341
326342macro_rules! biased_match_rec (
327343 // Handle the first layer
@@ -365,9 +381,9 @@ macro_rules! biased_match (
365381)
366382
367383
368- # enum T1 { Good1(T2, uint), Bad1};
384+ # enum T1 { Good1(T2, uint), Bad1}
369385# struct T2 { body: T3 }
370- # enum T3 { Good2(uint), Bad2};
386+ # enum T3 { Good2(uint), Bad2}
371387# fn f(x: T1) -> uint {
372388biased_match!(
373389 (x) ~ (Good1(g1, val)) else { return 0 };
@@ -376,6 +392,7 @@ biased_match!(
376392// complicated stuff goes here
377393return result + val;
378394# }
395+ # }
379396~~~~
380397
381398This technique applies to many cases where transcribing a result all at once is not possible.
0 commit comments