diff options
| author | Tyge Løvset <[email protected]> | 2023-02-22 14:35:56 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2023-02-22 15:05:27 +0100 |
| commit | b63df794ee2bda2c33856a646ca6e1386f5ab782 (patch) | |
| tree | 93ae40aca24ed5a71adfec252e2b4255db6f617b /misc/examples | |
| parent | a8fc8ac4e8c1481300e0d46bbd376f32ebeb4635 (diff) | |
| download | STC-modified-b63df794ee2bda2c33856a646ca6e1386f5ab782.tar.gz STC-modified-b63df794ee2bda2c33856a646ca6e1386f5ab782.zip | |
Added coroutines, based upon Simon Tatham's famous implementation. This version is much improved, but uses the same basic mechanisms.
Diffstat (limited to 'misc/examples')
| -rw-r--r-- | misc/examples/cofib.c | 40 | ||||
| -rw-r--r-- | misc/examples/coread.c | 41 |
2 files changed, 81 insertions, 0 deletions
diff --git a/misc/examples/cofib.c b/misc/examples/cofib.c new file mode 100644 index 00000000..d0e4ac2a --- /dev/null +++ b/misc/examples/cofib.c @@ -0,0 +1,40 @@ +#include <stc/algo/cco.h> +#include <stdio.h> +#include <stdint.h> + +// Use coroutine to create a fibonacci sequence generator: + +typedef long long llong; + +llong fibonacci_sequence(ccontext* ctx, unsigned n) { + assert (n < 95); + + cco_context(ctx, + llong a, b, idx; + ); + + cco_routine(u, + u->a = 0; + u->b = 1; + for (u->idx = 2; u->idx < n; u->idx++) { + llong sum = u->a + u->b; + cco_yield(sum); + u->a = u->b; + u->b = sum; + } + cco_finish: + ); + return 0; +} + + +int main(void) { + ccontext z = 0; + printf("Fibonacci numbers:\n"); + for (;;) { + llong x = fibonacci_sequence(&z, 30); + if (!z) break; + printf(" %lld", x); + } + puts(""); +} diff --git a/misc/examples/coread.c b/misc/examples/coread.c new file mode 100644 index 00000000..9181401d --- /dev/null +++ b/misc/examples/coread.c @@ -0,0 +1,41 @@ +#include <stc/cstr.h> +#include <stc/algo/cco.h> +#include <errno.h> + +// Read file line by line using coroutines: + +cstr file_nextline(ccontext* ccx, const char* name) +{ + cco_context(ccx, + FILE* fp; + cstr line; + ); + + cco_routine(U, + U->fp = fopen(name, "r"); + U->line = cstr_NULL; + + while (cstr_getline(&U->line, U->fp)) + cco_yield (cstr_clone(U->line)); + + cco_finish: // cco_finish is needed to support cco_stop. + printf("finish\n"); + cstr_drop(&U->line); + fclose(U->fp); + ); + return cstr_NULL; +} + + +int main(void) { + ccontext z = 0; + int n = 0; + do { + c_with (cstr line = file_nextline(&z, __FILE__), z, cstr_drop(&line)) { + printf("%3d %s\n", ++n, cstr_str(&line)); + + // stop after 10 lines: + if (n == 10) file_nextline(cco_stop(&z), __FILE__); + } + } while (z); +} |
