Skip to content

Instantly share code, notes, and snippets.

@mbillingr
Created March 7, 2019 15:39
Show Gist options
  • Save mbillingr/6c5495cd479881a0a8632ebad572e815 to your computer and use it in GitHub Desktop.
Save mbillingr/6c5495cd479881a0a8632ebad572e815 to your computer and use it in GitHub Desktop.
Runtime composition of closures
use std::collections::HashMap;
use std::rc::Rc;
type State = Vec<Object>;
type Closure = Rc<Fn(&mut State)>;
#[derive(Clone)]
enum Object {
Int(i32),
Clos(Closure),
}
impl std::fmt::Debug for Object {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Object::Int(i) => write!(f, "{}", i),
Object::Clos(_) => write!(f, "<native function>"),
}
}
}
fn compile(commands: &[&str], dict: &HashMap<&str, Closure>) -> Closure {
let ops: Vec<_> = commands
.iter()
.map(|op| dict.get(op).cloned().unwrap())
.collect();
Rc::new(move |state| {
for op in &ops {
op(state);
}
})
}
fn main() {
let mut dict: HashMap<_, Closure> = HashMap::new();
dict.insert(
"over",
Rc::new(|state: &mut State| {
let b = state.pop().unwrap();
let a = state.pop().unwrap();
state.push(a.clone());
state.push(b);
state.push(a);
}),
);
dict.insert(
"call",
Rc::new(|state: &mut State| match state.pop().unwrap() {
Object::Clos(f) => f(state),
_ => panic!("Type Error"),
}),
);
let two_dup = compile(&["over", "over"], &dict);
dict.insert("2dup", two_dup.clone());
let mut state = vec![Object::Int(2), Object::Int(10), Object::Clos(two_dup)];
println!("{:?}", state);
(dict.get("call").unwrap())(&mut state);
println!("{:?}", state);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment