Skip to content

Commit 7831d2d

Browse files
authored
Merge pull request #577 from taminomara/master
Export an array of all tokens from `ct_token_map`
2 parents 07f587b + 248fe3f commit 7831d2d

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

lrlex/src/lib/ctbuilder.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,14 +1185,17 @@ impl CTLexer {
11851185

11861186
/// Create a Rust module named `mod_name` that can be imported with
11871187
/// [`lrlex_mod!(mod_name)`](crate::lrlex_mod). The module contains one `const` `StorageT` per
1188-
/// token in `token_map`, with the token prefixed by `T_`. For example with `StorageT` `u8`,
1189-
/// `mod_name` `x`, and `token_map` `HashMap{"ID": 0, "INT": 1}` the generated module will look
1190-
/// roughly as follows:
1188+
/// token in `token_map`, with the token prefixed by `T_`. In addition, it will
1189+
/// contain an array of all token IDs `TOK_IDS`.
1190+
///
1191+
/// For example with `StorageT` `u8`, `mod_name` `x`, and `token_map`
1192+
/// `HashMap{"ID": 0, "INT": 1}` the generated module will look roughly as follows:
11911193
///
11921194
/// ```rust,ignore
11931195
/// mod x {
11941196
/// pub const T_ID: u8 = 0;
11951197
/// pub const T_INT: u8 = 1;
1198+
/// pub const TOK_IDS: &[u8] = &[T_ID, T_INT];
11961199
/// }
11971200
/// ```
11981201
///
@@ -1205,6 +1208,7 @@ impl CTLexer {
12051208
/// mod x {
12061209
/// pub const T_PLUS: u8 = 0;
12071210
/// pub const T_ID: u8 = 1;
1211+
/// pub const TOK_IDS: &[u8] = &[T_PLUS, T_ID];
12081212
/// }
12091213
/// ```
12101214
pub fn ct_token_map<StorageT: Display + ToTokens>(
@@ -1219,31 +1223,36 @@ pub fn ct_token_map<StorageT: Display + ToTokens>(
12191223
let timestamp = env!("VERGEN_BUILD_TIMESTAMP");
12201224
let mod_ident = format_ident!("{}", mod_name);
12211225
write!(outs, "// lrlex build time: {}\n\n", quote!(#timestamp),).ok();
1226+
let storaget = str::parse::<TokenStream>(type_name::<StorageT>()).unwrap();
12221227
// Sort the tokens so that they're always in the same order.
12231228
// This will prevent unneeded rebuilds.
12241229
let mut token_map_sorted = Vec::from_iter(token_map.borrow().iter());
12251230
token_map_sorted.sort_by_key(|(k, _)| *k);
1226-
let tokens = &token_map_sorted
1227-
.into_iter()
1231+
let (token_array, tokens): (TokenStream, TokenStream) = token_map_sorted
1232+
.iter()
12281233
.map(|(k, id)| {
12291234
let name = match rename_map {
12301235
Some(rmap) => *rmap.get(k.as_str()).unwrap_or(&k.as_str()),
1231-
_ => k,
1236+
_ => &k,
12321237
};
12331238
let tok_ident = format_ident!("T_{}", name.to_ascii_uppercase());
1234-
let storaget = str::parse::<TokenStream>(type_name::<StorageT>()).unwrap();
1235-
// Code gen for the constant token values.
1236-
quote! {
1237-
pub const #tok_ident: #storaget = #id;
1238-
}
1239+
(
1240+
quote! {
1241+
#tok_ident,
1242+
},
1243+
quote! {
1244+
pub const #tok_ident: #storaget = #id;
1245+
},
1246+
)
12391247
})
1240-
.collect::<Vec<_>>();
1248+
.unzip();
12411249
// Since the formatter doesn't preserve comments and we don't want to lose build time,
12421250
// just format the module contents.
12431251
let unformatted = quote! {
12441252
mod #mod_ident {
12451253
#![allow(dead_code)]
1246-
#(#tokens)*
1254+
#tokens
1255+
pub const TOK_IDS: &[#storaget] = &[#token_array];
12471256
}
12481257
}
12491258
.to_string();

0 commit comments

Comments
 (0)