-
-
Save lpereira/685608acbf1b0c9a1fe1881815ba6cad to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdbool.h> | |
struct coro { | |
void *state; | |
}; | |
struct range_coro { | |
struct coro base; | |
int cur, max, step; | |
}; | |
#define co_init(s) \ | |
if (!s->base.state) { \ | |
s->base.state = &&coroutine_init_label; \ | |
} else { \ | |
goto *s->base.state; \ | |
} \ | |
coroutine_init_label: \ | |
do { \ | |
} while (0) | |
#define co_yield__impl(s, val, counter) \ | |
do { \ | |
typeof(val) __ret__ = (val); \ | |
s->base.state = &&yield_point##counter; \ | |
return __ret__; \ | |
yield_point##counter:; \ | |
} while (0) | |
#define co_yield_impl(s, val, counter) co_yield__impl(s, val, counter) | |
#define co_yield(s, val) co_yield_impl(s, val, __COUNTER__) | |
int range(struct range_coro *rc) | |
{ | |
co_init(rc); | |
while (rc->cur <= rc->max) { | |
co_yield(rc, rc->cur); | |
rc->cur += rc->step; | |
} | |
while (true) { | |
co_yield(rc, -1); | |
} | |
} | |
struct inc_mul_coro { | |
struct coro base; | |
int cur; | |
}; | |
int inc_mul(struct inc_mul_coro *imc, int v) | |
{ | |
co_init(imc); | |
while (true) { | |
co_yield(imc, imc->cur * v); | |
imc->cur++; | |
} | |
} | |
struct inc_add_coro { | |
struct coro base; | |
int cur; | |
}; | |
int inc_add(struct inc_add_coro *iac, int v) | |
{ | |
co_init(iac); | |
while (true) { | |
co_yield(iac, iac->cur * v); | |
iac->cur++; | |
} | |
} | |
int main(int argc, char *argv[]) | |
{ | |
struct range_coro rc = { .cur = 0, .max = 100, .step = 7 }; | |
struct inc_mul_coro imc = {}; | |
struct inc_add_coro iac = {}; | |
int v; | |
while ((v = range(&rc)) >= 0) { | |
printf("%d\n", inc_add(&iac, inc_mul(&imc, v))); | |
} | |
printf("calling again: %d\n", range(&rc)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment