fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <inttypes.h>
  4.  
  5.  
  6. void push(uint32_t a, uint32_t **stackpp)
  7. {
  8. **stackpp = a;
  9. (*stackpp)++;
  10. }
  11.  
  12. uint32_t pop(uint32_t **stackpp)
  13. {
  14. (*stackpp)--;
  15. return **stackpp;
  16. }
  17.  
  18. uint32_t fib(uint32_t a)
  19. {
  20. uint32_t stack[10000] = {0};
  21. uint32_t *stackp = stack;
  22. uint32_t where_to_go;
  23.  
  24. // локальные дефайны
  25. #define PUSH(x) push(x, &stackp)
  26. #define POP() pop(&stackp)
  27. #define AFTER_P1 0
  28. #define AFTER_P2 1
  29. #define RESULT 2
  30. #define GOTO_VAL(x) do{where_to_go = (x); goto wtg_l;}while(0)
  31.  
  32. PUSH(RESULT);
  33. PUSH(a);
  34. while(stackp != stack)
  35. {
  36. uint32_t tmp = POP();
  37. if (tmp == 0)
  38. {
  39. uint32_t ret = POP();
  40. PUSH(0);
  41. GOTO_VAL(ret);
  42. }
  43. else if (tmp == 1)
  44. {
  45. uint32_t ret = POP();
  46. PUSH(1);
  47. GOTO_VAL(ret);
  48. }
  49. else
  50. {
  51. PUSH(tmp-2); // предварительно сохраняем
  52. PUSH( AFTER_P1 );
  53. PUSH(tmp-1);
  54. continue;
  55.  
  56. after_p1:;
  57. uint32_t tmp1 = POP(); // возвращенное значение
  58. uint32_t tmp2 = POP(); // предварительно сохраненное
  59. PUSH(tmp1);
  60. PUSH(AFTER_P2);
  61. PUSH(tmp2);
  62. continue;
  63.  
  64. after_p2:;
  65. uint32_t val = POP()+POP();
  66. int ret = POP();
  67. PUSH(val);
  68. GOTO_VAL(ret);
  69. }
  70. }
  71. // ERROR - стек размотался. Такого быть не должно
  72. exit(-1);
  73.  
  74. wtg_l:
  75. switch(where_to_go)
  76. {
  77. case AFTER_P1: goto after_p1;
  78. case AFTER_P2: goto after_p2;
  79. case RESULT: goto result;
  80. default: exit(-1); // хуйня какая-то, хуй знает куда прыгать
  81. }
  82.  
  83. result:
  84. return POP();
  85. // убираем локальные дефайны
  86. #undef PUSH
  87. #undef POP
  88. #undef AFTER_P1
  89. #undef AFTER_P2
  90. #undef RESULT
  91. #undef GOTO_VAL
  92. }
  93.  
  94. int main(void)
  95. {
  96. for(uint32_t i = 0; i < 30; i++)
  97. {
  98. printf("%" PRIu32 ", ", fib(i));
  99. }
  100. return EXIT_SUCCESS;
  101. }
Success #stdin #stdout 0.06s 5392KB
stdin
Standard input is empty
stdout
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,