Skip to content

Instantly share code, notes, and snippets.

@samrat
Created June 2, 2019 08:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samrat/e3df137f4e620d4f4c00ee4fafc5a893 to your computer and use it in GitHub Desktop.
Save samrat/e3df137f4e620d4f4c00ee4fafc5a893 to your computer and use it in GitHub Desktop.
Minimal AST uniquify example
use std::collections::HashMap;
use std::rc::Rc;
#[derive(Debug)]
enum AST {
Symbol(Rc<String>),
Int(i32),
Let(Vec<(Rc<String>, Box<AST>)>, Box<AST>),
}
static mut VAR_COUNTER : i32 = 0;
pub fn get_unique_varname(stem: &str) -> String {
unsafe {
VAR_COUNTER += 1;
return stem.to_string() + &VAR_COUNTER.to_string();
}
}
impl AST {
fn uniquify(self, mapping: &mut HashMap<Rc<String>, Rc<String>>) -> Self {
match self {
AST::Int(_) => self,
AST::Symbol(sym) => {
let uniq_sym = Rc::new(mapping.get(&sym)
.unwrap()
.to_string());
AST::Symbol(uniq_sym)
},
AST::Let(bindings, body) => {
let mut new_bindings = vec![];
for (k, v) in bindings {
let uniq_k = Rc::new(get_unique_varname(&k));
new_bindings.push((uniq_k.clone(),
Box::new(v.uniquify(mapping))));
mapping.insert(k, uniq_k.clone());
}
AST::Let(new_bindings,
Box::new(body.uniquify(mapping)))
},
}
}
}
fn main() {
let x = Rc::new("x".to_string());
// (let ((x 10))
// (let ((x 12))
// x))
let a = AST::Let(vec![(x.clone(), Box::new(AST::Int(10)))],
Box::new(AST::Let(vec![(x.clone(),
Box::new(AST::Int(12)))],
Box::new(AST::Symbol(x.clone())))));
let mut uniquify_mapping = HashMap::new();
println!("{:?}", a.uniquify(&mut uniquify_mapping));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment