Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 

217 wiersze
7.8 KiB

  1. #pragma once
  2. #include "platform.hpp"
  3. #ifdef FTB_WINDOWS
  4. #else
  5. # include <signal.h> // for sigtrap
  6. #endif
  7. #include <functional>
  8. #define proc auto
  9. #define concat(x, y) x ## y
  10. #define label(x, y) concat(x, y)
  11. #define line_label(x) label(x, __LINE__)
  12. #define MPI_LABEL(id1,id2) \
  13. concat(MPI_LABEL_ ## id1 ## _ ## id2 ## _, __LINE__)
  14. #define MPP_DECLARE(labid, declaration) \
  15. if (0) \
  16. ; \
  17. else \
  18. for (declaration;;) \
  19. if (1) { \
  20. goto MPI_LABEL(labid, body); \
  21. MPI_LABEL(labid, done): break; \
  22. } else \
  23. while (1) \
  24. if (1) \
  25. goto MPI_LABEL(labid, done); \
  26. else \
  27. MPI_LABEL(labid, body):
  28. #define MPP_BEFORE(labid,before) \
  29. if (1) { \
  30. before; \
  31. goto MPI_LABEL(labid, body); \
  32. } else \
  33. MPI_LABEL(labid, body):
  34. #define MPP_AFTER(labid,after) \
  35. if (1) \
  36. goto MPI_LABEL(labid, body); \
  37. else \
  38. while (1) \
  39. if (1) { \
  40. after; \
  41. break; \
  42. } else \
  43. MPI_LABEL(labid, body):
  44. // #ifndef min
  45. // #define min(a, b) ((a) < (b)) ? (a) : (b)
  46. // #endif
  47. // #ifndef max
  48. // #define max(a, b) ((a) > (b)) ? (a) : (b)
  49. // #endif
  50. /**
  51. * Defer *
  52. */
  53. template<typename F>
  54. class defer_finalizer {
  55. F f;
  56. bool moved;
  57. public:
  58. template<typename T>
  59. defer_finalizer(T && f_) : f(std::forward<T>(f_)), moved(false) { }
  60. defer_finalizer(const defer_finalizer &) = delete;
  61. defer_finalizer(defer_finalizer && other) : f(std::move(other.f)), moved(other.moved) {
  62. other.moved = true;
  63. }
  64. ~defer_finalizer() {
  65. if (!moved) f();
  66. }
  67. };
  68. static struct {
  69. template<typename F>
  70. defer_finalizer<F> operator<<(F && f) {
  71. return defer_finalizer<F>(std::forward<F>(f));
  72. }
  73. } deferrer;
  74. #define defer auto label(__deferred_lambda_call, __COUNTER__) = deferrer << [&]
  75. #define defer_free(var) defer { free(var); }
  76. /*
  77. defer {
  78. call();
  79. };
  80. expands to:
  81. auto __deferred_lambda_call0 = deferrer << [&] {
  82. call();
  83. };
  84. */
  85. #if defined(unix) || defined(__unix__) || defined(__unix)
  86. #define NULL_HANDLE "/dev/null"
  87. #else
  88. #define NULL_HANDLE "nul"
  89. #endif
  90. #define ignore_stdout \
  91. if (0) \
  92. label(finished,__LINE__): ; \
  93. else \
  94. for (FILE* label(fluid_let_, __LINE__) = ftb_stdout;;) \
  95. for (defer{ fclose(ftb_stdout); ftb_stdout=label(fluid_let_, __LINE__) ; } ;;) \
  96. if (1) { \
  97. ftb_stdout = fopen(NULL_HANDLE, "w"); \
  98. goto label(body,__LINE__); \
  99. } \
  100. else \
  101. while (1) \
  102. if (1) { \
  103. goto label(finished, __LINE__); \
  104. } \
  105. else label(body,__LINE__):
  106. /*****************
  107. * fluid-let *
  108. *****************/
  109. #define fluid_let(var, val) \
  110. if (0) \
  111. label(finished,__LINE__): ; \
  112. else \
  113. for (auto label(fluid_let_, __LINE__) = var;;) \
  114. for (defer{var = label(fluid_let_, __LINE__);};;) \
  115. for(var = val;;) \
  116. if (1) { \
  117. goto label(body,__LINE__); \
  118. } \
  119. else \
  120. while (1) \
  121. if (1) { \
  122. goto TOKENPASTE2(finished, __LINE__); \
  123. } \
  124. else TOKENPASTE2(body,__LINE__):
  125. ;
  126. /**
  127. fluid_let(var, val) {
  128. call1(var);
  129. call2(var);
  130. }
  131. expands to
  132. if (0)
  133. finished98:;
  134. else
  135. for (auto fluid_let_98 = var;;)
  136. for (auto __deferred_lambda_call0 = deferrer << [&] { var = fluid_let_98; };;)
  137. for (var = val;;)
  138. if (1) {
  139. goto body98;
  140. } else
  141. while (1)
  142. if (1) {
  143. goto finished98;
  144. } else
  145. body98 : {
  146. call1(var);
  147. call2(var);
  148. }
  149. */
  150. #define panic(...) \
  151. do { \
  152. print("%{color<}[Panic]%{>color} in " \
  153. "file %{color<}%{->char}%{>color} " \
  154. "line %{color<}%{u32}%{>color}: " \
  155. "(%{color<}%{->char}%{>color})\n", \
  156. console_red, console_cyan, __FILE__, console_cyan, __LINE__, \
  157. console_cyan, __func__); \
  158. print("%{color<}", console_red); \
  159. print(__VA_ARGS__); \
  160. print("%{>color}\n"); \
  161. fflush(stdout); \
  162. print_stacktrace(); \
  163. debug_break(); \
  164. } while(0)
  165. #define panic_if(cond, ...) \
  166. if(!(cond)); \
  167. else panic(__VA_ARGS__)
  168. #ifdef FTB_DEBUG_LOG
  169. # define debug_log(...) \
  170. do { \
  171. print("%{color<}[INFO " __FILE__ ":%{color<}%{->char}" \
  172. "%{>color}]%{>color} ", \
  173. console_green, console_cyan, __func__); \
  174. println(__VA_ARGS__); \
  175. } while (0)
  176. #else
  177. # define debug_log(...)
  178. #endif
  179. #ifdef FTB_WINDOWS
  180. # define debug_break() __debugbreak()
  181. #else
  182. # define debug_break() raise(SIGTRAP);
  183. #endif