Skip to content

Commit d40aeea

Browse files
committed
Describe behavior of switch and goto_block
1 parent 2f6a163 commit d40aeea

1 file changed

Lines changed: 53 additions & 11 deletions

File tree

libcc2rs-macros/src/lib.rs

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,65 @@ mod goto;
77
mod state_machine;
88
mod switch;
99

10-
// switch!(match <condition> {
11-
// <pat> [if <guard>] => <body>,
12-
// <pat> [if <guard>] => <body>,
13-
// ...
14-
// _ => <body>,
15-
// });
10+
// switch!(match <condition> {
11+
// <pat> [if <guard>] => { /* body; may contain break or continue */ },
12+
// ...
13+
// _ => <body>,
14+
// });
15+
//
16+
// Desugars to a goto_block! with a synthetic dispatch arm prepended.
17+
//
18+
// goto_block! {
19+
// '__dispatch => {
20+
// match <condition> {
21+
// <pat_1> => { __s = 1; continue '__sm; }
22+
// ...
23+
// _ => break '__sm,
24+
// }
25+
// },
26+
// '__c1 => { /* body_1 with `break` rewritten to `break '__sm` */ },
27+
// ...
28+
// '__cN => { /* body_N with same rewrite */ },
29+
// };
30+
//
31+
// __sm is the inner label used to describe the state machine insinde goto_block. See goto_block!
32+
// for more info.
1633

1734
#[proc_macro]
1835
pub fn switch(input: TokenStream) -> TokenStream {
1936
switch::expand(input)
2037
}
2138

22-
// goto_block! {
23-
// '<label> => <body>,
24-
// '<label> => <body>,
25-
// ...
26-
// };
39+
// goto_block! {
40+
// '<label> => { /* body; may contain `break` or `continue` */ },
41+
// ...
42+
// };
43+
//
44+
// Expands to
45+
//
46+
// {
47+
// let mut __user_break: bool = false; // only if any arm has `break`
48+
// let mut __user_continue: bool = false; // only if any arm has `continue`
49+
// let mut __s: u32 = 0;
50+
// '__sm: loop {
51+
// match __s {
52+
// 0u32 => {
53+
// /* body_0 with these rewrites (outside nested user loops): */
54+
// /* break; -> { __user_break = true; break '__sm; } */
55+
// /* continue; -> { __user_continue = true; break '__sm; } */
56+
// __s = 1; continue '__sm;
57+
// }
58+
// ...
59+
// (N-1)u32 => { /* body_N-1 with same rewrites */ break '__sm; }
60+
// _ => break '__sm, // written only for match exhaustiveness
61+
// }
62+
// }
63+
// if __user_break { break; } // only if any arm has `break;`
64+
// if __user_continue { continue; } // only if any arm has `continue;`
65+
// }
66+
//
67+
// __user_break and __user_continue propagate the `break`s and `continue`s outside the goto state
68+
// machine loop.
2769

2870
#[proc_macro]
2971
pub fn goto_block(input: TokenStream) -> TokenStream {

0 commit comments

Comments
 (0)