#include <stdio.h> #include <stdlib.h> #include <inttypes.h> void push(uint32_t a, uint32_t **stackpp) { **stackpp = a; (*stackpp)++; } uint32_t pop(uint32_t **stackpp) { (*stackpp)--; return **stackpp; } uint32_t fib(uint32_t a) { uint32_t stack[10000] = {0}; uint32_t *stackp = stack; uint32_t where_to_go; // локальные дефайны #define PUSH(x) push(x, &stackp) #define POP() pop(&stackp) #define AFTER_P1 0 #define AFTER_P2 1 #define RESULT 2 #define GOTO_VAL(x) do{where_to_go = (x); goto wtg_l;}while(0) PUSH(RESULT); PUSH(a); while(stackp != stack) { uint32_t tmp = POP(); if (tmp == 0) { uint32_t ret = POP(); PUSH(0); GOTO_VAL(ret); } else if (tmp == 1) { uint32_t ret = POP(); PUSH(1); GOTO_VAL(ret); } else { PUSH(tmp-2); // предварительно сохраняем PUSH( AFTER_P1 ); PUSH(tmp-1); continue; after_p1:; uint32_t tmp1 = POP(); // возвращенное значение uint32_t tmp2 = POP(); // предварительно сохраненное PUSH(tmp1); PUSH(AFTER_P2); PUSH(tmp2); continue; after_p2:; uint32_t val = POP()+POP(); int ret = POP(); PUSH(val); GOTO_VAL(ret); } } // ERROR - стек размотался. Такого быть не должно wtg_l: switch(where_to_go) { case AFTER_P1: goto after_p1; case AFTER_P2: goto after_p2; case RESULT: goto result; } result: return POP(); // убираем локальные дефайны #undef PUSH #undef POP #undef AFTER_P1 #undef AFTER_P2 #undef RESULT #undef GOTO_VAL } int main(void) { for(uint32_t i = 0; i < 30; i++) { } return EXIT_SUCCESS; }
Standard input is empty
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229,