use proc_macro2::Ident;
use quote::format_ident;
fn modify_path(mut path: syn::Path, prefix: &str) -> syn::Path {
let segment = path.segments.last_mut().expect("rule path");
let x = format_ident!("{}_{}", prefix, segment.ident);
segment.ident = x;
path
}
pub fn parser_name(rule_path: syn::Path) -> syn::Path {
modify_path(rule_path, "parse")
}
pub fn recognizer_name(rule_path: syn::Path) -> syn::Path {
modify_path(rule_path, "recognize")
}
pub fn parser_id(id: Ident) -> Ident {
format_ident!("parse_{}", id)
}
pub fn recognizer_id(id: Ident) -> Ident {
format_ident!("recognize_{}", id)
}
pub struct NameFactory
{
prefix_uid: usize,
mark_uid: usize,
branch_failed_uid: usize,
counter_uid: usize,
closure_uid: usize
}
impl NameFactory
{
pub fn new() -> NameFactory {
NameFactory {
prefix_uid: 1,
mark_uid: 0,
branch_failed_uid: 0,
counter_uid: 0,
closure_uid: 0
}
}
pub fn next_mark_name(&mut self) -> Ident {
self.mark_uid += 1;
format_ident!("mark{}", self.mark_uid)
}
pub fn next_branch_failed_name(&mut self) -> Ident {
self.branch_failed_uid += 1;
format_ident!("branch_failed_{}", self.branch_failed_uid)
}
pub fn next_closure_name(&mut self) -> Ident {
self.closure_uid += 1;
format_ident!("success_continuation_{}", self.closure_uid)
}
pub fn next_counter_name(&mut self) -> Ident {
self.counter_uid += 1;
format_ident!("counter{}", self.counter_uid)
}
pub fn fresh_vars(&mut self, cardinality: usize) -> Vec<Ident> {
let prefix = self.next_var_prefix();
(0..cardinality)
.map(|i| format_ident!("{}{}", prefix, i))
.collect()
}
pub fn next_var_prefix(&mut self) -> String {
const LETTERS: &'static [u8] = b"abcdefghijklmnopqrstuvwxyz";
let mut prefix = String::new();
let mut num_letter = self.prefix_uid;
while num_letter > 0 {
let x = num_letter % LETTERS.len();
num_letter /= LETTERS.len();
prefix.push(LETTERS[x] as char);
}
self.prefix_uid += 1;
prefix
}
}