Skip to content

Instantly share code, notes, and snippets.

@wehu
Last active August 29, 2015 14:19
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 wehu/8b17d65eeb2c34b028c8 to your computer and use it in GitHub Desktop.
Save wehu/8b17d65eeb2c34b028c8 to your computer and use it in GitHub Desktop.
A partial implementation of delimited continuation
fn expand_shift0(b: &Fn(&Fn()), k: &Fn()) {
b(k);
}
//fn expand_shift1<B>(b: &Fn(&Fn() -> B) -> B, k: &Fn() -> B) -> B {
// b(k)
//}
//fn expand_shift2<A, B>(b: &Fn(&Fn(A) -> B) -> B, k: &Fn(A) -> B) -> B {
// b(k)
//}
macro_rules! reset {
(; $($b:tt)*) => (reset!($($b)*));
(shift |$k:ident| {
$($b:tt)*
}
$($res:tt)*) => (expand_shift0(&|$k| {
reset!($($b)*)
},
&|| {
reset!($($res)*)
}));
(cps $f:ident ($($e:expr),*) $($res:tt)* ) => ($f (&|| {
reset!($($res)*)
},
$($e),*));
(if $e:expr {
$($t:tt)*
} else {
$($f:tt)*
}
$($res:tt)*) => (
if $e {
reset!($($t)*; $($res)*)
} else {
reset!($($f)*; $($res)*)
});
(if $e:expr {
$($t:tt)*
}
$($res:tt)*) => (
if $e {
reset!($($t)*; $($res)*)
});
(while $e:expr {
$($b:tt)*
}
$($res:tt)*) => {{
struct Fact<'a> { f: &'a Fn(&Fact, &Fn())};
let f = &Fact {
f: &|f: &Fact, k: &Fn()|{ reset!(if $e {$($b)*; (f.f)(f, k);} else {k();};)}
};
(f.f)(f, &||{reset!($($res)*)});
}};
{$s:stmt} => {{$s}};
{$s:stmt ; $($res:tt)* } => {{$s ; reset!($($res)*) }};
() => {{}};
}
macro_rules! cps {
(fn $f:ident ($($a:ident : $t:ty),*) {$($b:tt)*}) => (
fn $f (k: &Fn(), $($a : $t),*) {
reset!($($b)*; k(););
}
)
}
cps!(fn foo (){
println!("dd");
shift |k| {
k();
};
println!("aa");
});
fn main() {
reset!{
println!("aaa");
shift |k| {
k();
shift |k| {
k();
};
println!("aa");
};
cps foo();
println!("bb");
if true {
shift |k| { println!("if"); k();};
} else {
;
};
while true {
shift |k| { println!("while"); }
};
println!("cc");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment