#include <stdio.h>
#include <stdlib.h>
typedef struct {int phase; void* data;} HCOROUTINE;
#define COROUTINE(name, ...) name(HCOROUTINE* __coroutine_phase, ##__VA_ARGS__)
#define COBEGIN(args) struct { args }** __coroutine_dataref=(typeof(__coroutine_dataref))&__coroutine_phase->data;\
switch(__coroutine_phase->phase){case 0: do{*__coroutine_dataref=malloc(sizeof(**__coroutine_dataref));}while(0);
#define STATE (**__coroutine_dataref)
#define YIELD(x) do{__coroutine_phase->phase=__LINE__; return x;}while(0); case __LINE__:{}
#define COEND };__coroutine_phase->phase=-1; free(*__coroutine_dataref);
#define NEXT(st, coro, ...) (coro(&st, ##__VA_ARGS__))
#define ENDED(x) ((x.phase)==-1)
typedef int COROUTINE_PHASE;
int COROUTINE(hello){
COBEGIN(int a;)
STATE.a=1;
printf("Hello, %d, for the first time!\n", STATE.a);
STATE.a=2;
YIELD(114)
printf("Hello, %d, for the second time!\n", STATE.a);
STATE.a=3;
YIELD(514)
printf("Hello, %d, for the last time!\n", STATE.a);
YIELD(810)
COEND
return 893;
}
int main(void) {
printf("Hello World!\n");
HCOROUTINE st={};
while(!ENDED(st)){
int ret=NEXT(st, hello);
printf("Coroutine yielded %d\n", ret);
}
return 0;
}