Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- typedef struct psync_state {void *lbl; void *data;} psync_state;
- #define CONCAT1(a, b) a ## b
- #define CONCAT2(a, b) CONCAT1(a, b)
- #define PDECL(ret, name, ...) \
- typedef ret name ## _ret; \
- psync_state name(psync_state _psync_st, __VA_ARGS__)
- #define _PSTRUCT(var) typeof(var) var;
- #define _PASSIGN(var) var = _psync_args->var;
- #define _PCOMMA(var) var,
- #define _PSTVAR(_) _(_psync_call)
- #define PINIT() \
- psync_state _psync_call; \
- struct _pstruct {PVARS(_PSTRUCT) _PSTVAR(_PSTRUCT)} *_psync_args; \
- if(!_psync_st.lbl){ \
- _psync_args = malloc(sizeof(struct _pstruct)); \
- }else{ \
- _psync_args = _psync_st.data; \
- PVARS(_PASSIGN) \
- _PSTVAR(_PASSIGN) \
- goto *_psync_st.lbl; \
- }
- #define PWAIT(lbl) \
- *_psync_args = (struct _pstruct){PVARS(_PCOMMA) _PSTVAR(_PCOMMA)}; \
- return (psync_state){&&lbl, _psync_args}; \
- lbl:
- #define PCALL(func, ...) ({ \
- _psync_call = (psync_state){0}; \
- _psync_call = func(_psync_call, __VA_ARGS__); \
- while(_psync_call.lbl){ \
- PWAIT(CONCAT2(func, CONCAT2(_call_, __COUNTER__))); \
- _psync_call= func(_psync_call, __VA_ARGS__); \
- } \
- *(func ## _ret*)_psync_call.data; \
- })
- #define PRET(var) \
- *(typeof(var)*)_psync_args = var; \
- return (psync_state){0, _psync_args};
- PDECL(int, add, int, int);
- PDECL(int, add, int a, int b) {
- int c;
- #define PVARS(_) _(a) _(b) _(c)
- PINIT()
- c = 0;
- c += a;
- PWAIT(add_b)
- c += b;
- PRET(c)
- #undef PVARS
- }
- PDECL(int, add3, int a, int b, int c){
- int d;
- #define PVARS(_) _(a) _(b) _(c) _(d)
- PINIT()
- d = 0;
- d = PCALL(add, d, a);
- d = PCALL(add, d, b);
- d = PCALL(add, d, c);
- PRET(d);
- #undef PVARS
- }
- int main(void){
- struct psync_state st1, st2;
- st1 = add3((psync_state){0}, 10, 25, 13);
- st2 = add3((psync_state){0}, 100, -30, 25);
- while(st1.lbl || st2.lbl){
- if(st1.lbl) st1 = add3(st1, 0,0,0);
- if(st2.lbl) st2 = add3(st2, 0,0,0);
- }
- printf("1: %d\n", *((add3_ret*)st1.data));
- printf("2: %d\n", *((add3_ret*)st2.data));
- free(st1.data);
- free(st2.data);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement