#include #include #include #include #define STACK_MAX 65536 typedef struct frame_s { struct frame_s *f_back; int state; } frame_t; struct frame_0_s { frame_t header; }; struct frame_1_s { frame_t header; int i1; }; char* stack_base; frame_t* frame_stack_top; frame_t* frame_stack_bottom; int restart_substate; int retval_int; frame_t* new_frame(int size, int state); void *save_frame_0(int state); void *save_frame_1(int state, int i1); void stack_check(void); /************************************************************/ int clamp(int n) { return n % 1291; } int triangle(int n) { int a, b, c, d; if (frame_stack_top) goto resume; stack_check(); if (frame_stack_bottom) goto save_0; resume_0: if (n <= 0) { //sleep(2); return 0; } a = n - 1; b = triangle(a); if (frame_stack_bottom) goto save_1; resume_1: c = b + n; d = clamp(c); if (frame_stack_bottom) goto save_2; resume_2: return d; save_0: return (int) save_frame_1(0, n); save_1: return (int) save_frame_1(1, n); save_2: return (int) save_frame_0(2); resume: { frame_t* f = frame_stack_top; frame_stack_top = NULL; switch (restart_substate) { case 0: n = ((struct frame_1_s*) f)->i1; goto resume_0; case 1: n = ((struct frame_1_s*) f)->i1; b = retval_int; goto resume_1; case 2: d = retval_int; goto resume_2; } assert(0); } } void stack_check(void) { char local; if (frame_stack_top) goto resume; if ((stack_base - &local) > STACK_MAX) { frame_stack_top = frame_stack_bottom = new_frame(sizeof(struct frame_0_s), 3); fprintf(stderr, "."); return; } resume_0: return; resume: { frame_t* f = frame_stack_top; frame_stack_top = NULL; switch (restart_substate) { case 0: goto resume_0; } assert(0); } } /************************************************************/ struct state_decoding_entry_s { void *function; int signature; }; struct state_decoding_entry_s state_decoding_table[] = { { triangle, 1 }, // 0 { NULL, 1 }, // 1 { NULL, 2 }, // 2 { stack_check, 0 }, // 3 }; void main_loop(void) { int state, signature; frame_t* pending; frame_t* back; void* fn; while (1) { frame_stack_bottom = NULL; pending = frame_stack_top; while (1) { back = pending->f_back; state = pending->state; fn = state_decoding_table[state].function; signature = state_decoding_table[state].signature; if (fn != NULL) restart_substate = 0; else { restart_substate = signature; state -= signature; fn = state_decoding_table[state].function; signature = state_decoding_table[state].signature; } switch (signature) { case 0: ((void(*)(void)) fn) (); break; case 1: retval_int = ((int(*)(int)) fn) (0); break; } free(pending); /* consumed by the previous call */ if (frame_stack_bottom) break; if (!back) return; pending = back; frame_stack_top = pending; } assert(frame_stack_bottom->f_back == NULL); frame_stack_bottom->f_back = back; } } int main() { int n; char local; stack_base = &local; frame_stack_top = new_frame(sizeof(struct frame_1_s), 0); ((struct frame_1_s*) frame_stack_top)->i1 = 1000000; main_loop(); n = retval_int; printf("%d\n", n); assert(n == 704); } /************************************************************/ frame_t* new_frame(int size, int state) { frame_t* f = (frame_t*) malloc(size); f->f_back = NULL; f->state = state; return f; } void *save_frame_0(int state) { frame_t* f = new_frame(sizeof(struct frame_0_s), state); frame_stack_bottom->f_back = f; frame_stack_bottom = f; return NULL; } void *save_frame_1(int state, int i1) { frame_t* f = new_frame(sizeof(struct frame_1_s), state); frame_stack_bottom->f_back = f; frame_stack_bottom = f; ((struct frame_1_s*) f)->i1 = i1; return NULL; }