@@ -72,6 +72,54 @@ fn get_byte_from_expr_lit(expr: &Box<syn::Expr>) -> u8 {
7272 }
7373}
7474
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+
75123/// Expand a TokenStream corresponding to the `match_byte` macro.
76124///
77125/// ## Example
@@ -97,48 +145,8 @@ fn expand_match_byte(body: &TokenStream) -> syn::Expr {
97145 let case_id = i + 1 ;
98146 let index = case_id as isize ;
99147 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) ;
100149
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- }
142150 cases. push ( quote ! ( #name = #index) ) ;
143151 let body = & arm. body ;
144152 match_body. push ( quote ! ( Case :: #name => { #body } ) )
@@ -170,7 +178,7 @@ impl Fold for MatchByteParser {
170178 if mac. path == parse_quote ! ( match_byte) {
171179 return syn:: fold:: fold_stmt (
172180 self ,
173- syn:: Stmt :: Expr ( expand_match_byte ( & mac. tts ) ) ,
181+ syn:: Stmt :: Expr ( expand_match_byte ( & mac. tokens ) ) ,
174182 ) ;
175183 }
176184 }
@@ -184,7 +192,7 @@ impl Fold for MatchByteParser {
184192 match expr {
185193 syn:: Expr :: Macro ( syn:: ExprMacro { ref mac, .. } ) => {
186194 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 ) ) ;
188196 }
189197 }
190198 _ => { }
0 commit comments