diff options
| author | Tyge Løvset <[email protected]> | 2023-02-27 09:57:33 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2023-02-27 10:16:59 +0100 |
| commit | d37820ddc211aec2876950cd4f2236cc9b92c9eb (patch) | |
| tree | 79a2fd040b214d2904860115cb8e6c888a973ff7 | |
| parent | 31459ecefc0d54399eafd9a18303868625f57a7c (diff) | |
| download | STC-modified-d37820ddc211aec2876950cd4f2236cc9b92c9eb.tar.gz STC-modified-d37820ddc211aec2876950cd4f2236cc9b92c9eb.zip | |
Let cco_end(value) return value. Should be last in function anyway.
Assume context always non-NULL when calling cco_alive(context).
| -rw-r--r-- | include/stc/algo/coroutine.h | 35 | ||||
| -rw-r--r-- | misc/examples/coread.c | 6 | ||||
| -rw-r--r-- | misc/examples/coroutines.c | 11 |
3 files changed, 23 insertions, 29 deletions
diff --git a/include/stc/algo/coroutine.h b/include/stc/algo/coroutine.h index 6e36750d..da15aa5b 100644 --- a/include/stc/algo/coroutine.h +++ b/include/stc/algo/coroutine.h @@ -35,40 +35,41 @@ struct iterate { int y; }; -bool iterate(struct iterate* U) { - cco_begin(U); - for (U->x = 0; U->x < U->max_x; U->x++) - for (U->y = 0; U->y < U->max_y; U->y++) - cco_yield (true); +bool iterate(struct iterate* I) { + cco_begin(I); + for (I->x = 0; I->x < I->max_x; I->x++) + for (I->y = 0; I->y < I->max_y; I->y++) + cco_yield(true); cco_final: puts("final"); - cco_end(U); - return false; + cco_end(false); } int main(void) { - struct iterate it = {3, 3}; + struct iterate it = {.max_x=3, .max_y=3}; int n = 0; while (iterate(&it)) { printf("%d %d\n", it.x, it.y); - if (++n == 20) { iterate(cco_stop(&it)); break; } + // example of early stop: + if (++n == 20) (void)cco_stop(&it); // signal to stop at next } return 0; } */ #include <stc/ccommon.h> -#define cco_begin(c) \ - int *_state = &(c)->cco_state; \ +#define cco_begin(ctx) \ + int *_state = &(ctx)->cco_state; \ switch (*_state) { \ case 0: -#define cco_end() \ +#define cco_end(retval) \ *_state = 0; break; \ default: assert(!"missing cco_final: or illegal state"); \ - } + } \ + return retval #define cco_yield(retval) \ do { \ @@ -76,15 +77,15 @@ int main(void) { case __LINE__:; \ } while (0) -#define cco_yield_coroutine(c, corocall, retval) \ +#define cco_yield_coroutine(ctx, corocall, retval) \ do { \ *_state = __LINE__; \ c_PASTE(cco, __LINE__): corocall; return retval; \ - case __LINE__:; if (cco_alive(c)) goto c_PASTE(cco, __LINE__); \ + case __LINE__:; if (cco_alive(ctx)) goto c_PASTE(cco, __LINE__); \ } while (0) #define cco_final case -1 -#define cco_alive(c) ((c) && (c)->cco_state > 0) -#define cco_stop(c) ((c)->cco_state = ((c)->cco_state > 0 ? -1 : -2), c) +#define cco_alive(ctx) ((ctx)->cco_state > 0) +#define cco_stop(ctx) ((ctx)->cco_state = cco_alive(ctx) ? -1 : -2), ctx) #endif diff --git a/misc/examples/coread.c b/misc/examples/coread.c index 3d49c5df..4df80339 100644 --- a/misc/examples/coread.c +++ b/misc/examples/coread.c @@ -24,8 +24,7 @@ bool file_nextline(struct file_nextline* U) printf("finish\n"); cstr_drop(&U->line); fclose(U->fp); - cco_end(); - return false; + cco_end(false); } int main(void) { @@ -33,9 +32,6 @@ int main(void) { int n = 0; while (file_nextline(&z)) { printf("%3d %s\n", ++n, cstr_str(&z.line)); - - // stop after 15 lines: - if (n == 15) (void)cco_stop(&z); } printf("state %d\n", z.cco_state); } diff --git a/misc/examples/coroutines.c b/misc/examples/coroutines.c index 5d2a178a..89b428ee 100644 --- a/misc/examples/coroutines.c +++ b/misc/examples/coroutines.c @@ -17,8 +17,7 @@ bool iterate(struct iterate* I) { for (I->y = 0; I->y < I->max_y; I->y++) cco_yield(true); cco_final: - cco_end(); - return false; + cco_end(false); } // Use coroutine to create a fibonacci sequence generator: @@ -42,9 +41,7 @@ int64_t fibonacci(struct fibonacci* F) { F->b = sum; } cco_final: - cco_end(); - - return -1; + cco_end(-1); } // Combine @@ -60,10 +57,10 @@ bool combine(struct combine* C) { cco_yield_coroutine(&C->it, iterate(&C->it), true); cco_yield_coroutine(&C->fib, fibonacci(&C->fib), true); // May reuse the C->it context; state has been reset to 0. + C->it.max_x = 2; C->it.max_y = 2; cco_yield_coroutine(&C->it, iterate(&C->it), true); cco_final: puts("final"); - cco_end(); - return false; + cco_end(false); } int main(void) { |
