Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 

122 Zeilen
3.9 KiB

  1. #pragma once
  2. #include <functional>
  3. #define proc auto
  4. #define concat(x, y) x ## y
  5. #define label(x, y) concat(x, y)
  6. /**
  7. * Defer *
  8. */
  9. template<typename F>
  10. class defer_finalizer {
  11. F f;
  12. bool moved;
  13. public:
  14. template<typename T>
  15. defer_finalizer(T && f_) : f(std::forward<T>(f_)), moved(false) { }
  16. defer_finalizer(const defer_finalizer &) = delete;
  17. defer_finalizer(defer_finalizer && other) : f(std::move(other.f)), moved(other.moved) {
  18. other.moved = true;
  19. }
  20. ~defer_finalizer() {
  21. if (!moved) f();
  22. }
  23. };
  24. static struct {
  25. template<typename F>
  26. defer_finalizer<F> operator<<(F && f) {
  27. return defer_finalizer<F>(std::forward<F>(f));
  28. }
  29. } deferrer;
  30. #define defer auto label(__deferred_lambda_call, __COUNTER__) = deferrer << [&]
  31. #define defer_free(var) defer { free(var); }
  32. /*
  33. defer {
  34. call();
  35. };
  36. expands to:
  37. auto __deferred_lambda_call0 = deferrer << [&] {
  38. call();
  39. };
  40. */
  41. #define ignore_stdout \
  42. if (0) \
  43. label(finished,__LINE__): ; \
  44. else \
  45. for (FILE* tmp = ftb_stdout;;) \
  46. for (defer{ fclose(ftb_stdout); ftb_stdout= tmp; } ;;) \
  47. if (1) { \
  48. ftb_stdout = fopen("nul", "w"); \
  49. goto label(body,__LINE__); \
  50. } \
  51. else \
  52. while (1) \
  53. if (1) { \
  54. goto label(finished, __LINE__); \
  55. } \
  56. else label(body,__LINE__):
  57. /*****************
  58. * fluid-let *
  59. *****************/
  60. #define fluid_let(var, val) \
  61. if (0) \
  62. label(finished,__LINE__): ; \
  63. else \
  64. for (auto label(fluid_let_, __LINE__) = var;;) \
  65. for (defer{var = label(fluid_let_, __LINE__);};;) \
  66. for(var = val;;) \
  67. if (1) { \
  68. goto label(body,__LINE__); \
  69. } \
  70. else \
  71. while (1) \
  72. if (1) { \
  73. goto TOKENPASTE2(finished, __LINE__); \
  74. } \
  75. else TOKENPASTE2(body,__LINE__):
  76. /**
  77. fluid_let(var, val) {
  78. call1(var);
  79. call2(var);
  80. }
  81. expands to
  82. if (0)
  83. finished98:;
  84. else
  85. for (auto fluid_let_98 = var;;)
  86. for (auto __deferred_lambda_call0 = deferrer << [&] { var = fluid_let_98; };;)
  87. for (var = val;;)
  88. if (1) {
  89. goto body98;
  90. } else
  91. while (1)
  92. if (1) {
  93. goto finished98;
  94. } else
  95. body98 : {
  96. call1(var);
  97. call2(var);
  98. }
  99. */