Skip to content

Instantly share code, notes, and snippets.

@erickt
Created December 18, 2015 17:49
Show Gist options
  • Save erickt/3313d728efe3e715e452 to your computer and use it in GitHub Desktop.
Save erickt/3313d728efe3e715e452 to your computer and use it in GitHub Desktop.
#![feature(plugin)]
#![plugin(stateful)]
#![allow(unused_variables)]
fn increment(x: usize) -> usize { x + 1 }
#[state_machine]
fn yield_(a: usize) -> usize {
let x = increment(a);
{
let y = increment(x);
return x + y;
let z = increment(y);
return x + y + z;
};
return x;
}
fn main() {
for value in yield_(1) {
println!("yield_: {:?}", value);
}
}
#![feature(prelude_import)]
#![no_std]
#![feature(plugin)]
#![plugin(stateful)]
#![allow(unused_variables)]
#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate std as std;
fn increment(x: usize) -> usize {
x + 1
}
fn yield_(a: usize) -> ::std::boxed::Box<::std::iter::Iterator<Item = usize>> {
struct Wrapper<S, F> {
state: S,
next: F,
}
impl<S, T, F> Wrapper<S, F> where F: Fn(S) -> (Option<T>, S)
{
fn new(initial_state: S, next: F) -> Self {
Wrapper {
state: initial_state,
next: next,
}
}
}
impl<S, T, F> Iterator for Wrapper<S, F>
where S: Default,
F: Fn(S) -> (Option<T>, S)
{
type
Item
=
T;
fn next(&mut self) -> Option<Self::Item> {
let old_state = ::std::mem::replace(&mut self.state, S::default());
let (value, next_state) = (self.next)(old_state);
self.state = next_state;
value
}
}
enum State<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> {
State0Entry(T0),
State2BlockEntry(T1),
State3BlockEntry(T2, T3),
State4Yield(T4, T5, T6),
State5Yield(T7, T8, T9, T10),
State6BlockExit(T11, T12),
State7Yield(T13, T14),
State8BlockExit(T15),
State1Exit,
}
impl <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
T15> Default for
State<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
T15> {
fn default() -> Self { State::State1Exit }
}
Box::new(Wrapper::new(State::State0Entry(a), |mut state| {
loop {
match state {
State::State0Entry(a) => {
state = State::State2BlockEntry(a);
continue;
}
State::State2BlockEntry(a) => {
let x = increment(a);
{
state = State::State3BlockEntry(a, x);
continue;
}
}
State::State3BlockEntry(a, x) => {
let y = increment(x);
return (::std::option::Option::Some(x + y),
State::State4Yield(a, x, y));
}
State::State4Yield(a, x, y) => {
let z = increment(y);
return (::std::option::Option::Some(x + y + z),
State::State5Yield(a, x, y, z));
}
State::State5Yield(a, x, y, z) => {
state = State::State6BlockExit(a, x);
continue;
}
State::State6BlockExit(a, x) => {
return (::std::option::Option::Some(x), State::State7Yield(a, x));
}
State::State7Yield(a, x) => {
state = State::State8BlockExit(a);
continue;
}
State::State8BlockExit(a) => {
state = State::State1Exit;
continue;
}
State::State1Exit => {
return (::std::option::Option::None, State::State1Exit);
}
}
}
}))
}
fn main() {
for value in yield_(1) {
::std::io::_print(::std::fmt::Arguments::new_v1({
static __STATIC_FMTSTR:
&'static [&'static str]
=
&["yield_: ",
"\n"];
__STATIC_FMTSTR
},
&match (&value,) {
(__arg0,) =>
[::std::fmt::ArgumentV1::new(__arg0,
::std::fmt::Debug::fmt)],
}));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment