Created
March 7, 2019 15:39
-
-
Save mbillingr/6c5495cd479881a0a8632ebad572e815 to your computer and use it in GitHub Desktop.
Runtime composition of closures
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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