1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| int hanoi(int n, char from, char to, char via) { Frame stk[64]; Frame *top = stk - 1;
#define call(...) ({ *(++top) = (Frame){.pc = 0, __VA_ARGS__}; }) #define ret(val) ({ top--; retval = (val); })
int retval = 0;
call(n, from, to, via);
while (1) { Frame *f = top; printf("pc=%d\n", f->pc); if (top < stk) { break; }
int next_pc = f->pc + 1;
int n = f->n, from = f->from, to = f->to, via = f->via; switch (f->pc) { case 0: if (n == 1) { printf("%c -> %c\n", from, to); ret(1); } break; case 1: call(n - 1, from, via, to); break; case 2: f->c1 = retval; break; case 3: call(1, from, to, via); break; case 4: call(n - 1, via, to, from); break; case 5: f->c2 = retval; break; case 6: ret(f->c1 + f->c2 + 1); break; default: assert(0); }
f->pc = next_pc; }
return retval; }
|