diff options
| author | Tyge Løvset <[email protected]> | 2023-02-23 20:40:48 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2023-02-23 20:40:48 +0100 |
| commit | 95656f384672748dcf02c256e23534728bef80d9 (patch) | |
| tree | 8ae535749a40f2a2f5c7a716bd339b177f657bef | |
| parent | fadfc47abd5f8fe0757244b3b9eb5a1ae78e0dce (diff) | |
| download | STC-modified-95656f384672748dcf02c256e23534728bef80d9.tar.gz STC-modified-95656f384672748dcf02c256e23534728bef80d9.zip | |
Replaced coroutine.h with ccoro.h. Stackbased only.
| -rw-r--r-- | include/stc/algo/ccoro.h | 90 | ||||
| -rw-r--r-- | misc/examples/cofib.c | 31 | ||||
| -rw-r--r-- | misc/examples/coread.c | 32 |
3 files changed, 124 insertions, 29 deletions
diff --git a/include/stc/algo/ccoro.h b/include/stc/algo/ccoro.h new file mode 100644 index 00000000..f5c682e8 --- /dev/null +++ b/include/stc/algo/ccoro.h @@ -0,0 +1,90 @@ +/* MIT License + * + * Copyright (c) 2023 Tyge Løvset + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef STC_CCORO_INCLUDED +#define STC_CCORO_INCLUDED +/* +#include <stdio.h> +#include <stdbool.h> +#include <stc/algo/ccoro.h> + +struct iterate { + int max_x; + int max_y; + int ccoro_state; // required member + int x; + int y; +}; + +bool iterate(struct iterate* U) { + ccoro_execute(U, + for (U->x = 0; U->x < U->max_x; U->x++) + for (U->y = 0; U->y < U->max_y; U->y++) + ccoro_yield (true); + + ccoro_final: puts("final"); + ); + return false; +} + +int main(void) { + struct iterate it = {3, 3}; + int n = 0; + while (iterate(&it)) + { + printf("%d %d\n", it.x, it.y); + if (++n == 20) { iterate(ccoro_stop(&it)); break; } + } + return 0; +} +*/ +#include <stc/ccommon.h> + +#define ccoro_execute(c, ...) \ + int* _state = &(c)->ccoro_state; \ + switch (*_state) { \ + case 0:; __VA_ARGS__ break; \ + default: assert(!"missing ccoro_finish: or illegal state"); \ + } \ + *_state = -2 + +#define ccoro_yield(...) c_MACRO_OVERLOAD(ccoro_yield, __VA_ARGS__) +#define ccoro_yield_1(value) \ + do { \ + *_state = __LINE__; return value; \ + case __LINE__:; \ + } while (0) + +#define ccoro_yield_2(subcoro, c) \ + do { \ + *_state = __LINE__; \ + c_PASTE(coro, __LINE__): \ + return subcoro; \ + case __LINE__:; \ + if (ccoro_alive(c)) goto c_PASTE(coro, __LINE__); \ + } while (0) + +#define ccoro_final case -1 +#define ccoro_stop(c) ((c)->ccoro_state = (c)->ccoro_state > 0 ? -1 : -2, c) +#define ccoro_alive(c) ((c)->ccoro_state >= 0) + +#endif diff --git a/misc/examples/cofib.c b/misc/examples/cofib.c index ea37669a..b58775ae 100644 --- a/misc/examples/cofib.c +++ b/misc/examples/cofib.c @@ -1,27 +1,29 @@ -#include <stc/algo/coroutine.h> +#include <stc/algo/ccoro.h> #include <stdio.h> #include <stdint.h> // Use coroutine to create a fibonacci sequence generator: typedef long long llong; +struct fibonacci { + int n; + int ccoro_state; + llong a, b, idx; +}; -llong fibonacci_sequence(cco_handle* z, unsigned n) { - assert (n < 95); +llong fibonacci(struct fibonacci* U) { + assert (U->n < 95); - cco_context(z, - llong a, b, idx; - ); - cco_routine(U, + ccoro_execute(U, U->a = 0; U->b = 1; - for (U->idx = 0; U->idx < n; U->idx++) { - cco_yield (U->a); - llong sum = U->a + U->b; // NB! locals only lasts until next cco_yield! + for (U->idx = 0; U->idx < U->n; U->idx++) { + ccoro_yield (U->a); + llong sum = U->a + U->b; // NB! locals only lasts until next ccoro_yield! U->a = U->b; U->b = sum; } - cco_finish: + ccoro_final: ); return -1; @@ -29,11 +31,12 @@ llong fibonacci_sequence(cco_handle* z, unsigned n) { int main(void) { - cco_handle z = 0; printf("Fibonacci numbers:\n"); + struct fibonacci fib = {.n = 14}; + for (;;) { - llong x = fibonacci_sequence(&z, 14); - if (!z) break; + llong x = fibonacci(&fib); + if (!ccoro_alive(&fib)) break; printf(" %lld", x); } puts(""); diff --git a/misc/examples/coread.c b/misc/examples/coread.c index e65ab533..a3eac7f9 100644 --- a/misc/examples/coread.c +++ b/misc/examples/coread.c @@ -1,41 +1,43 @@ #include <stc/cstr.h> -#include <stc/algo/coroutine.h> +#include <stc/algo/ccoro.h> #include <errno.h> // Read file line by line using coroutines: -cstr file_nextline(cco_handle* z, const char* name) +struct file_nextline { + const char* filename; + int ccoro_state; + FILE* fp; + cstr line; +}; + +cstr file_nextline(struct file_nextline* U) { - cco_context(z, - FILE* fp; - cstr line; - ); - cco_routine(U, - U->fp = fopen(name, "r"); + ccoro_execute(U, + U->fp = fopen(U->filename, "r"); U->line = cstr_NULL; while (cstr_getline(&U->line, U->fp)) - cco_yield (cstr_clone(U->line)); + ccoro_yield (cstr_clone(U->line)); - cco_finish: // cco_finish is needed to support cco_stop. + ccoro_final: // ccoro_final is needed to support ccoro_stop. printf("finish\n"); cstr_drop(&U->line); fclose(U->fp); ); - return cstr_NULL; } int main(void) { - cco_handle z = 0; + struct file_nextline z = {__FILE__}; int n = 0; do { - c_with (cstr line = file_nextline(&z, __FILE__), z, cstr_drop(&line)) { + c_with (cstr line = file_nextline(&z), ccoro_alive(&z), cstr_drop(&line)) { printf("%3d %s\n", ++n, cstr_str(&line)); // stop after 15 lines: - if (n == 15) file_nextline(cco_stop(&z), __FILE__); + if (n == 15) file_nextline(ccoro_stop(&z)); } - } while (z); + } while (ccoro_alive(&z)); } |
