summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/stc/algo/coroutine.h31
-rw-r--r--misc/examples/coread.c5
-rw-r--r--misc/examples/coroutines.c27
-rw-r--r--misc/examples/triples.c3
4 files changed, 33 insertions, 33 deletions
diff --git a/include/stc/algo/coroutine.h b/include/stc/algo/coroutine.h
index 89ac9a35..bf000779 100644
--- a/include/stc/algo/coroutine.h
+++ b/include/stc/algo/coroutine.h
@@ -28,11 +28,9 @@
#include <stc/algo/coroutine.h>
struct iterate {
- int max_x;
- int max_y;
+ int max_x, max_y;
+ int x, y;
int cco_state; // required member
- int x;
- int y;
};
bool iterate(struct iterate* I) {
@@ -66,6 +64,8 @@ enum {
cco_state_illegal = -3,
};
+#define cco_alive(ctx) ((ctx)->cco_state > 0)
+
#define cco_begin(ctx) \
int *_state = &(ctx)->cco_state; \
switch (*_state) { \
@@ -74,16 +74,11 @@ enum {
#define cco_end(retval) \
*_state = cco_state_expired; break; \
- default: assert(!"missing cco_final: or illegal state"); \
- goto cco_finish; /* avoid unused warning */ \
+ default: assert(!"illegal coroutine state"); \
+ goto _cco_final_; /* avoid unused-warning */ \
} \
return retval
-#define cco_return \
- do { \
- *_state = cco_state_final; goto cco_finish; \
- } while (0)
-
#define cco_yield(...) c_MACRO_OVERLOAD(cco_yield, __VA_ARGS__)
#define cco_yield_1(retval) \
do { \
@@ -98,9 +93,15 @@ enum {
case __LINE__: if (cco_alive(ctx)) goto c_PASTE(cco, __LINE__); \
} while (0)
-#define cco_final case cco_state_final: cco_finish
-#define cco_stop(ctx) (((ctx)->cco_state = cco_alive(ctx) ? \
- cco_state_final : cco_state_illegal), ctx)
-#define cco_alive(ctx) ((ctx)->cco_state > 0)
+#define cco_final \
+ case cco_state_final: \
+ _cco_final_
+
+#define cco_return \
+ goto _cco_final_
+
+#define cco_stop(ctx) \
+ (((ctx)->cco_state = cco_alive(ctx) ? \
+ cco_state_final : cco_state_illegal), ctx)
#endif
diff --git a/misc/examples/coread.c b/misc/examples/coread.c
index 4df80339..c5f85e08 100644
--- a/misc/examples/coread.c
+++ b/misc/examples/coread.c
@@ -15,12 +15,12 @@ bool file_nextline(struct file_nextline* U)
{
cco_begin(U)
U->fp = fopen(U->filename, "r");
- U->line = cstr_NULL;
+ U->line = cstr_init();
while (cstr_getline(&U->line, U->fp))
cco_yield(true);
- cco_final: // cco_final is needed to support cco_stop.
+ cco_final: // required label.
printf("finish\n");
cstr_drop(&U->line);
fclose(U->fp);
@@ -33,5 +33,4 @@ int main(void) {
while (file_nextline(&z)) {
printf("%3d %s\n", ++n, cstr_str(&z.line));
}
- printf("state %d\n", z.cco_state);
}
diff --git a/misc/examples/coroutines.c b/misc/examples/coroutines.c
index 577ef8c1..2c9e6d5c 100644
--- a/misc/examples/coroutines.c
+++ b/misc/examples/coroutines.c
@@ -52,15 +52,18 @@ bool fibonacci(struct fibonacci* F) {
assert(F->count < 94);
cco_begin(F);
- F->idx = 1;
+ F->idx = 0;
F->result = 0;
F->b = 1;
- for (;; F->idx++) {
- if (F->count-- == 0) cco_return;
+ for (;;) {
+ if (F->count-- == 0)
+ cco_return;
+ if (++F->idx > 1) {
+ int64_t sum = F->result + F->b; // NB! locals only lasts until next cco_yield!
+ F->result = F->b;
+ F->b = sum;
+ }
cco_yield(true);
- int64_t sum = F->result + F->b; // NB! locals only lasts until next cco_yield!
- F->result = F->b;
- F->b = sum;
}
cco_final:
printf("final fib\n");
@@ -69,29 +72,29 @@ bool fibonacci(struct fibonacci* F) {
// Combine
-struct combine {
+struct combined {
struct prime prm;
struct fibonacci fib;
int cco_state;
};
-bool combine(struct combine* C) {
+bool combined(struct combined* C) {
cco_begin(C);
cco_yield(prime(&C->prm), &C->prm, true);
cco_yield(fibonacci(&C->fib), &C->fib, true);
// Reuse the C->prm context and extend the count:
- C->prm.count = 20;
+ C->prm.count = 8; C->prm.result += 2;
cco_yield(prime(&C->prm), &C->prm, true);
- cco_final: puts("final");
+ cco_final: puts("final comb");
cco_end(false);
}
int main(void) {
- struct combine comb = {.prm={.count=10}, .fib={14}};
+ struct combined comb = {.prm={.count=8}, .fib={14}};
if (true)
- while (combine(&comb))
+ while (combined(&comb))
printf("Prime(%d)=%lld, Fib(%d)=%lld\n",
comb.prm.idx, (long long)comb.prm.result,
comb.fib.idx, (long long)comb.fib.result);
diff --git a/misc/examples/triples.c b/misc/examples/triples.c
index 05e6fca2..0ce0eb37 100644
--- a/misc/examples/triples.c
+++ b/misc/examples/triples.c
@@ -23,8 +23,6 @@ struct tricoro {
int x, y, z;
};
-#include <stdlib.h>
-
bool triples_coro(struct tricoro* t) {
cco_begin(t);
for (t->z = 1;; ++t->z) {
@@ -38,7 +36,6 @@ bool triples_coro(struct tricoro* t) {
}
}
cco_final:
- puts("final");
cco_end(false);
}