fibonacci/fibonacci.rs
1// Copyright 2016 coroutine-rs Developers
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8extern crate context;
9
10use context::{Context, Transfer};
11use context::stack::ProtectedFixedSizeStack;
12
13// Print the natural numbers from 0 to 9 using a "generator" preserving state on the stack.
14fn main() {
15 // This method will always `resume()` immediately back to the
16 // previous `Context` with a `data` value of the next number in the fibonacci sequence.
17 // You could thus describe this method as a "fibonacci sequence generator".
18 extern "C" fn context_function(mut t: Transfer) -> ! {
19 let mut a = 0usize;
20 let mut b = 1usize;
21
22 loop {
23 print!("Yielding {} => ", a);
24 t = unsafe { t.context.resume(a) };
25
26 let next = a + b;
27 a = b;
28 b = next;
29 }
30 }
31
32 // Allocate some stack.
33 let stack = ProtectedFixedSizeStack::default();
34
35 // Allocate a Context on the stack.
36 let mut t = Transfer::new(unsafe { Context::new(&stack, context_function) }, 0);
37
38 // Yield 10 times to `context_function()`.
39 for _ in 0..10 {
40 // Yield to the "frozen" state of `context_function()`.
41 // The `data` value is not used in this example and is left at 0.
42 // The first and every other call will return references to the actual `Context` data.
43 print!("Resuming => ");
44 t = unsafe { t.context.resume(0) };
45
46 println!("Got {}", t.data);
47 }
48
49 println!("Finished!");
50}