All pastes #1399117 Raw Edit

Mine

public c v1 · immutable
#1399117 ·published 2009-04-22 01:36 UTC
rendered paste body
#include <stdio.h>#include <stdlib.h>/* co-routines in (gnu) c   inspired by http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html   instead of using an offet to a jump table, it's possible to use   an offset to a code label in GNU C   labels as values are defined here:    http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html    like sgtathams code, we store an offset to jump back into   the function but we use a direct jmp instead of an internal jump table.   *//* the preprocessor works in mysterious ways */#define __NAME__    __LABEL__(__LINE__)#define __LABEL__(x) __LABEL2__(x)#define __LABEL2__(x) __next##__##xtypedef unsigned int __offset__;#define CORO_STRUCT(x) typedef struct {__offset__ __state__; struct x;}#define CORO_MALLOC(t,cr) \    t *cr = malloc(sizeof(t));\    cr -> __state__ = 0#define CORO_STATIC(cr,t,in)  \    static t (cr) = {0,in}; \    CORO_INIT(cr)#define CORO_INIT(cr) \    goto *(&&__init__ + (cr).__state__); \    __init__: /* use offsets instead of label addresses, to   make code relocatable*/#define YIELD(cr, ...)  { \    (cr).__state__ =  &&__NAME__ - &&__init__; \    return __VA_ARGS__; \    } __NAME__:/* possible cleanup code */#define FAIL(cr) {}CORO_STRUCT({int i;})  foo_cr;/* example coroutine */int foo_static() {    CORO_STATIC(cr,foo_cr, {10});    while (cr.i--) {        YIELD(cr,cr.i);    }    return 0;}int foo_dynamic(foo_cr *cr) {    CORO_INIT(*cr);    cr->i = 9;    while ((cr->i)--) {        YIELD(*cr,cr->i);    }    return 0;}int main () {    int a;    while (1) {        a = foo_static();        if (a <= 0) break;        printf("-%d\n",a);    }       CORO_MALLOC(foo_cr,cr);     while (1) {        a = foo_dynamic(cr);        if (a <= 0) break;        printf("%d\n",a);    }    free(cr);    return 0;}