Advertisement
Guest User

Untitled

a guest
May 29th, 2015
285
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.26 KB | None | 0 0
  1. # A Study on Coroutines in plain C
  2.  
  3. This approach provides a very simple implementation of asymmetric coroutines.
  4. Unfortunately, unlike Python's Generators, this solution has no means of state preservation.
  5. The only thing one can do with these coroutines is iterate through them until full exhaustion or until manual halt.
  6.  
  7. ### How to Use it
  8.  
  9. One defines coroutines almost as regular C routines, yet with `coroutine` keyword.
  10. Defined coroutines can later be invoked with `take` construct.
  11. Apart from being a regular routine, a coroutine can, within its body,
  12. either `yield` to provide the consumer with one generated value,
  13. or `return` to immediately cease execution thus producing no further values.
  14. Each time a coroutine `yield`s, the control flow passes to consumer party to `take` statement
  15. with its iterator set to just `yield`ed value.
  16.  
  17. Within its body, `take` has the pre-declared iterator,
  18. and two additional keywords: `next` and `stop`.
  19. These keywords are used to decide whether the execution
  20. of iterated coroutine should continue.
  21. Each control branch of a `take` body should always end with either `next` or `stop`.
  22.  
  23. ### Symbols
  24.  
  25. `coroutine.h` module introduces five keywords.
  26. * `coroutine` declares a new one.
  27. The first argument is return type of the declared coroutine, and the second argument is its name.
  28. This order is taken from C routine declaration: instead of `int fib()` one would write `coroutine(int, fib)`.
  29. Naturally, since these coroutines cannot keep their state, there is no need in input arguments to them.
  30. * `take` consumes a coroutine's yield.
  31. First argument is iterator type, has to be the same as return type of the coroutine being consumed.
  32. Second argument is the name of iterator. Third argument is the name of a previously defined coroutine.
  33. Fourth argument is the loop body, which would have access to the iterator as defined with first and second argument.
  34. Mnemonic: `take [int] each in <coro> with <this body>`.
  35. * `yield` is used in coroutine body to set the iterator value.
  36. * `next` is used in consumer body to claim more values from iterated coroutine if there are any.
  37. * `stop` is used in consumer body to interrupt the execution flow of the iterated coroutine.
  38. If `stop`ped, the last `yield` behaves like `return`.
  39.  
  40. ### Platform
  41. This works on Clang and GCC.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement