@@ -72,6 +72,54 @@ fn get_byte_from_expr_lit(expr: &Box<syn::Expr>) -> u8 {
72
72
}
73
73
}
74
74
75
+ /// Parse a pattern and fill the table accordingly
76
+ fn parse_pat_to_table < ' a > ( pat : & ' a syn:: Pat , case_id : u8 , wildcard : & mut Option < & ' a syn:: Ident > , table : & mut [ u8 ; 256 ] ) {
77
+ match pat {
78
+ & syn:: Pat :: Lit ( syn:: PatLit { ref expr, .. } ) => {
79
+ let value = get_byte_from_expr_lit ( expr) ;
80
+ if table[ value as usize ] == 0 {
81
+ table[ value as usize ] = case_id;
82
+ }
83
+ }
84
+ & syn:: Pat :: Range ( syn:: PatRange { ref lo, ref hi, .. } ) => {
85
+ let lo = get_byte_from_expr_lit ( lo) ;
86
+ let hi = get_byte_from_expr_lit ( hi) ;
87
+ for value in lo..hi {
88
+ if table[ value as usize ] == 0 {
89
+ table[ value as usize ] = case_id;
90
+ }
91
+ }
92
+ if table[ hi as usize ] == 0 {
93
+ table[ hi as usize ] = case_id;
94
+ }
95
+ }
96
+ & syn:: Pat :: Wild ( _) => {
97
+ for byte in table. iter_mut ( ) {
98
+ if * byte == 0 {
99
+ * byte = case_id;
100
+ }
101
+ }
102
+ }
103
+ & syn:: Pat :: Ident ( syn:: PatIdent { ref ident, .. } ) => {
104
+ assert_eq ! ( * wildcard, None ) ;
105
+ * wildcard = Some ( ident) ;
106
+ for byte in table. iter_mut ( ) {
107
+ if * byte == 0 {
108
+ * byte = case_id;
109
+ }
110
+ }
111
+ } ,
112
+ & syn:: Pat :: Or ( syn:: PatOr { ref cases, .. } ) => {
113
+ for case in cases {
114
+ parse_pat_to_table ( case, case_id, wildcard, table) ;
115
+ }
116
+ }
117
+ _ => {
118
+ panic ! ( "Unexpected pattern: {:?}. Buggy code ?" , pat) ;
119
+ }
120
+ }
121
+ }
122
+
75
123
/// Expand a TokenStream corresponding to the `match_byte` macro.
76
124
///
77
125
/// ## Example
@@ -97,48 +145,8 @@ fn expand_match_byte(body: &TokenStream) -> syn::Expr {
97
145
let case_id = i + 1 ;
98
146
let index = case_id as isize ;
99
147
let name = syn:: Ident :: new ( & format ! ( "Case{}" , case_id) , Span :: call_site ( ) ) ;
148
+ parse_pat_to_table ( & arm. pat , case_id as u8 , & mut wildcard, & mut table) ;
100
149
101
- for pat in & arm. pats {
102
- match pat {
103
- & syn:: Pat :: Lit ( syn:: PatLit { ref expr } ) => {
104
- let value = get_byte_from_expr_lit ( expr) ;
105
- if table[ value as usize ] == 0 {
106
- table[ value as usize ] = case_id as u8 ;
107
- }
108
- }
109
- & syn:: Pat :: Range ( syn:: PatRange { ref lo, ref hi, .. } ) => {
110
- let lo = get_byte_from_expr_lit ( lo) ;
111
- let hi = get_byte_from_expr_lit ( hi) ;
112
- for value in lo..hi {
113
- if table[ value as usize ] == 0 {
114
- table[ value as usize ] = case_id as u8 ;
115
- }
116
- }
117
- if table[ hi as usize ] == 0 {
118
- table[ hi as usize ] = case_id as u8 ;
119
- }
120
- }
121
- & syn:: Pat :: Wild ( _) => {
122
- for byte in table. iter_mut ( ) {
123
- if * byte == 0 {
124
- * byte = case_id as u8 ;
125
- }
126
- }
127
- }
128
- & syn:: Pat :: Ident ( syn:: PatIdent { ref ident, .. } ) => {
129
- assert_eq ! ( wildcard, None ) ;
130
- wildcard = Some ( ident) ;
131
- for byte in table. iter_mut ( ) {
132
- if * byte == 0 {
133
- * byte = case_id as u8 ;
134
- }
135
- }
136
- }
137
- _ => {
138
- panic ! ( "Unexpected pattern: {:?}. Buggy code ?" , pat) ;
139
- }
140
- }
141
- }
142
150
cases. push ( quote ! ( #name = #index) ) ;
143
151
let body = & arm. body ;
144
152
match_body. push ( quote ! ( Case :: #name => { #body } ) )
@@ -170,7 +178,7 @@ impl Fold for MatchByteParser {
170
178
if mac. path == parse_quote ! ( match_byte) {
171
179
return syn:: fold:: fold_stmt (
172
180
self ,
173
- syn:: Stmt :: Expr ( expand_match_byte ( & mac. tts ) ) ,
181
+ syn:: Stmt :: Expr ( expand_match_byte ( & mac. tokens ) ) ,
174
182
) ;
175
183
}
176
184
}
@@ -184,7 +192,7 @@ impl Fold for MatchByteParser {
184
192
match expr {
185
193
syn:: Expr :: Macro ( syn:: ExprMacro { ref mac, .. } ) => {
186
194
if mac. path == parse_quote ! ( match_byte) {
187
- return syn:: fold:: fold_expr ( self , expand_match_byte ( & mac. tts ) ) ;
195
+ return syn:: fold:: fold_expr ( self , expand_match_byte ( & mac. tokens ) ) ;
188
196
}
189
197
}
190
198
_ => { }
0 commit comments