Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 

102 рядки
2.7 KiB

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