1 use crate::util::ToIdent;
2 use proc_macro2::{Literal, TokenStream};
3 use quote::{quote, ToTokens};
4 use syn::Ident;
5 
6 pub struct TableStack {
7     tables: Vec<(Ident, [u8; 256])>,
8     shift: u8,
9 }
10 
11 pub struct TableView<'a> {
12     ident: &'a Ident,
13     table: &'a mut [u8; 256],
14     mask: u8,
15 }
16 
17 impl TableStack {
new() -> Self18     pub fn new() -> Self {
19         TableStack {
20             tables: vec![("COMPACT_TABLE_0".to_ident(), [0; 256])],
21             shift: 0,
22         }
23     }
24 
view(&mut self) -> TableView25     pub fn view(&mut self) -> TableView {
26         let mask = if self.shift < 8 {
27             // Reusing existing table with a shifted mask
28             let mask = 1u8 << self.shift;
29 
30             self.shift += 1;
31 
32             mask
33         } else {
34             // Need to create a new table
35             let ident = format!("COMPACT_TABLE_{}", self.tables.len()).to_ident();
36 
37             self.tables.push((ident, [0; 256]));
38             self.shift = 1;
39 
40             1
41         };
42 
43         let (ref ident, ref mut table) = self.tables.last_mut().unwrap();
44 
45         TableView { ident, table, mask }
46     }
47 }
48 
49 impl<'a> TableView<'a> {
ident(&self) -> &'a Ident50     pub fn ident(&self) -> &'a Ident {
51         self.ident
52     }
53 
flag(&mut self, byte: u8)54     pub fn flag(&mut self, byte: u8) {
55         self.table[byte as usize] |= self.mask;
56     }
57 
mask(&self) -> Literal58     pub fn mask(&self) -> Literal {
59         Literal::u8_unsuffixed(self.mask)
60     }
61 }
62 
63 impl ToTokens for TableStack {
to_tokens(&self, out: &mut TokenStream)64     fn to_tokens(&self, out: &mut TokenStream) {
65         if self.shift == 0 {
66             return;
67         }
68 
69         for (ident, table) in self.tables.iter() {
70             let bytes = table.iter().copied().map(Literal::u8_unsuffixed);
71 
72             out.extend(quote! {
73                 static #ident: [u8; 256] = [#(#bytes),*];
74             });
75         }
76     }
77 }
78