1use std::cell::RefCell;
2use std::rc::Rc;
3use std::sync::atomic::AtomicUsize;
4
5use crate::Str;
6
7#[derive(Debug, Default)]
8pub struct FreshNameGenerator {
9 id: AtomicUsize,
10 prefix: &'static str,
12}
13
14impl FreshNameGenerator {
15 pub const fn new(prefix: &'static str) -> Self {
16 Self {
17 id: AtomicUsize::new(0),
18 prefix,
19 }
20 }
21
22 pub fn fresh_varname(&self) -> Str {
23 self.id.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
24 let i = self.id.load(std::sync::atomic::Ordering::SeqCst);
25 Str::from(format!("%v_{}_{i}", self.prefix))
26 }
27
28 pub fn fresh_param_name(&self) -> Str {
29 self.id.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
30 let i = self.id.load(std::sync::atomic::Ordering::SeqCst);
31 Str::from(format!("%p_{}_{i}", self.prefix))
32 }
33}
34
35pub static FRESH_GEN: FreshNameGenerator = FreshNameGenerator::new("global");
36
37#[derive(Debug, Clone, Default)]
38pub struct SharedFreshNameGenerator(Rc<RefCell<FreshNameGenerator>>);
39
40impl SharedFreshNameGenerator {
41 pub fn new(prefix: &'static str) -> Self {
42 Self(Rc::new(RefCell::new(FreshNameGenerator::new(prefix))))
43 }
44
45 pub fn fresh_varname(&self) -> Str {
46 self.0.borrow_mut().fresh_varname()
47 }
48
49 pub fn fresh_param_name(&self) -> Str {
50 self.0.borrow_mut().fresh_param_name()
51 }
52}