Skip to content

Instantly share code, notes, and snippets.

@aisamanra
Created October 2, 2019 18:10
Show Gist options
  • Save aisamanra/07983471f6a6d1d0b156b878f8c4ba7c to your computer and use it in GitHub Desktop.
Save aisamanra/07983471f6a6d1d0b156b878f8c4ba7c to your computer and use it in GitHub Desktop.
#[derive(Debug)]
enum Expr {
Var { x: u32 },
App { f: ExprRef, arg: ExprRef },
Lam { body: ExprRef },
}
use Expr::*;
#[derive(Debug, Copy, Clone)]
struct ExprRef {
idx: usize,
}
struct Context {
contents: Vec<Expr>,
}
impl Context {
fn new() -> Context {
Context { contents: Vec::new() }
}
fn add_expr(&mut self, expr: Expr) -> ExprRef {
self.contents.push(expr);
ExprRef { idx: self.contents.len() - 1}
}
fn var(&mut self, x: u32) -> ExprRef {
self.add_expr(Var { x })
}
fn app(&mut self, f: ExprRef, arg: ExprRef) -> ExprRef {
self.add_expr(App { f, arg })
}
fn lam(&mut self, body: ExprRef) -> ExprRef {
self.add_expr(Lam { body })
}
fn get(&self, expr: ExprRef) -> &Expr {
&self.contents[expr.idx]
}
fn show_expr(&self, expr: ExprRef) -> String{
match self.get(expr) {
Var { x } => format!("Var({})", *x),
App { f, arg } => format!("App({}, {})", self.show_expr(*f), self.show_expr(*arg)),
Lam { body } => format!("Lam({})", self.show_expr(*body)),
}
}
}
fn main() {
let mut ctx = Context::new();
let v1 = ctx.var(1);
let v2 = ctx.var(1);
let l1 = ctx.lam(v1);
let l2 = ctx.lam(l1);
let app = ctx.app(l2, v2);
let ctx = ctx; // remove mutability so we can no longer add new values
println!("{}", ctx.show_expr(app));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment