use fnv;
use crate::ast::ExprKind::*;
use crate::ast::*;
use std::cmp::max;
use std::iter;
pub mod colors;
pub mod dump;
pub mod stats;
#[derive(Debug, Clone)]
pub struct SymbolGenerator {
id_map: fnv::FnvHashMap<String, i32>,
}
impl SymbolGenerator {
pub fn new() -> SymbolGenerator {
SymbolGenerator {
id_map: fnv::FnvHashMap::default(),
}
}
pub fn from_expression(expr: &Expr) -> SymbolGenerator {
let mut id_map: fnv::FnvHashMap<String, i32> = fnv::FnvHashMap::default();
let update_id = |id_map: &mut fnv::FnvHashMap<String, i32>, symbol: &Symbol| {
let id = id_map.entry(symbol.name()).or_insert(0);
*id = max(*id, symbol.id());
};
expr.traverse(&mut |e| match e.kind {
Let { ref name, .. } => update_id(&mut id_map, name),
Ident(ref sym) => update_id(&mut id_map, sym),
Lambda { ref params, .. } => {
for p in params.iter() {
update_id(&mut id_map, &p.name);
}
}
_ => {}
});
SymbolGenerator { id_map }
}
pub fn new_symbol(&mut self, name: &str) -> Symbol {
let id = self.id_map.entry(name.to_owned()).or_insert(-1);
*id += 1;
Symbol::new(name, *id)
}
}
pub fn join<T: iter::Iterator<Item = String>>(
start: &str,
sep: &str,
end: &str,
strings: T,
) -> String {
let mut res = String::new();
res.push_str(start);
for (i, s) in strings.enumerate() {
if i > 0 {
res.push_str(sep);
}
res.push_str(&s);
}
res.push_str(end);
res
}