No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 
 
 

155 líneas
15 KiB

  1. #define concat_( a, b) a##b
  2. #define label(prefix, lnum) concat_(prefix,lnum)
  3. #define log_location() \
  4. do { \
  5. if (Globals::log_level == Log_Level::Debug) { \
  6. printf("in"); \
  7. int spacing = 30-(int)strlen(__FILE__); \
  8. if (spacing < 1) spacing = 1; \
  9. for (int i = 0; i < spacing;++i) \
  10. printf(" "); \
  11. printf("%s (%d) ", __FILE__, __LINE__); \
  12. printf("-> %s\n",__FUNCTION__); \
  13. } \
  14. } while(0)
  15. #define if_error_log_location_and_return(val) \
  16. do { \
  17. if (Globals::error) { \
  18. log_location(); \
  19. return val; \
  20. } \
  21. } while(0)
  22. #ifdef _DEBUG
  23. #define try_or_else_return(val) \
  24. if (1) \
  25. goto label(body,__LINE__); \
  26. else \
  27. while (1) \
  28. if (1) { \
  29. if (Globals::error) { \
  30. log_location(); \
  31. return val; \
  32. } \
  33. break; \
  34. } \
  35. else label(body,__LINE__):
  36. ;
  37. #else
  38. #define try_or_else_return(val)
  39. #endif
  40. #define try_struct try_or_else_return({})
  41. #define try_void try_or_else_return()
  42. #define try try_or_else_return(0)
  43. #define dont_break_on_errors fluid_let(Globals::breaking_on_errors, false)
  44. #define ignore_logging fluid_let(Globals::log_level, Log_Level::None)
  45. #define fetch1(var) \
  46. Lisp_Object* var##_symbol = Memory::get_symbol(#var); \
  47. Lisp_Object* var = lookup_symbol(var##_symbol, get_current_environment()); \
  48. if (Globals::error) printf("in %s:%d\n", __FILE__, __LINE__)
  49. #define fetch2(var1, var2) fetch1(var1); fetch1(var2)
  50. #define fetch3(var1, var2, var3) fetch2(var1, var2); fetch1(var3)
  51. #define fetch4(var1, var2, var3, var4) fetch3(var1, var2, var3); fetch1(var4)
  52. #define fetch5(var1, var2, var3, var4, var5) fetch4(var1, var2, var3, var4); fetch1(var5)
  53. #define fetch6(var1, var2, var3, var4, var5, var6) fetch5(var1, var2, var3, var4, var5); fetch1(var6)
  54. #define fetch7(var1, var2, var3, var4, var5, var6, var7) fetch6(var1, var2, var3, var4, var5, var6); fetch1(var7)
  55. #define fetch8(var1, var2, var3, var4, var5, var6, var7, var8) fetch7(var1, var2, var3, var4, var5, var6, var7); fetch1(var8)
  56. #define fetch9(var1, var2, var3, var4, var5, var6, var7, var8, var9) fetch8(var1, var2, var3, var4, var5, var6, var7, var8); fetch1(var9)
  57. #define fetch10(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10) fetch9(var1, var2, var3, var4, var5, var6, var7, var8, var9); fetch1(var10)
  58. #define fetch11(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11) fetch10(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10); fetch1(var11)
  59. #define fetch12(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12) fetch11(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11); fetch1(var12)
  60. #define fetch13(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13) fetch12(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12); fetch1(var13)
  61. #define fetch14(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14) fetch13(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13); fetch1(var14)
  62. #define fetch15(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15) fetch14(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14); fetch1(var15)
  63. #define fetch16(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16) fetch15(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15); fetch1(var16)
  64. #define fetch17(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17) fetch16(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16); fetch1(var17)
  65. #define fetch18(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18) fetch17(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17); fetch1(var18)
  66. #define fetch19(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19) fetch18(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18); fetch1(var19)
  67. #define fetch20(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20) fetch19(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19); fetch1(var20)
  68. #define fetch21(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20, var21) fetch20(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20); fetch1(var21)
  69. #define fetch22(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20, var21, var22) fetch21(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20, var21); fetch1(var22)
  70. #define fetch23(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20, var21, var22, var23) fetch22(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20, var21, var22); fetch1(var23)
  71. #define fetch24(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20, var21, var22, var23, var24) fetch23(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20, var21, var22, var23); fetch1(var24)
  72. #define GET_MACRO( \
  73. _1, _2, _3, _4, _5, _6, \
  74. _7, _8, _9, _10, _11, _12, \
  75. _13, _14, _15, _16, _17, _18, \
  76. _19, _20, _21, _22, _23, _24, \
  77. NAME, ...) NAME
  78. #ifdef _MSC_VER
  79. #define EXPAND( x ) x
  80. #define fetch(...) EXPAND( \
  81. GET_MACRO( \
  82. __VA_ARGS__, \
  83. fetch24, fetch23, fetch22, fetch21, fetch20, fetch19, \
  84. fetch18, fetch17, fetch16, fetch15, fetch14, fetch13, \
  85. fetch12, fetch11, fetch10, fetch9, fetch8, fetch7, \
  86. fetch6, fetch5, fetch4, fetch3, fetch2, fetch1 \
  87. )(__VA_ARGS__))
  88. #else
  89. #define fetch(...) \
  90. GET_MACRO( \
  91. __VA_ARGS__, \
  92. fetch24, fetch23, fetch22, fetch21, fetch20, fetch19, \
  93. fetch18, fetch17, fetch16, fetch15, fetch14, fetch13, \
  94. fetch12, fetch11, fetch10, fetch9, fetch8, fetch7, \
  95. fetch6, fetch5, fetch4, fetch3, fetch2, fetch1 \
  96. )(__VA_ARGS__)
  97. #endif
  98. // NOTE(Felix): we have to copy the string because we need it to be
  99. // mutable for the parser to work, because the parser relys on being
  100. // able to temporaily put in markers in the code and also it will fill
  101. // out the source code location
  102. #define _define_helper(def, docs, special) \
  103. Parser::parser_file = file_name_built_ins; \
  104. Parser::parser_line = __LINE__; \
  105. Parser::parser_col = 0; \
  106. auto label(params,__LINE__) = Parser::parse_single_expression( \
  107. Memory::get_c_str(Memory::create_string(#def))); \
  108. if_error_log_location_and_return(nullptr); \
  109. assert_type(label(params,__LINE__), Lisp_Object_Type::Pair); \
  110. assert_type(label(params,__LINE__)->value.pair.first, Lisp_Object_Type::Symbol); \
  111. auto label(sym,__LINE__) = label(params,__LINE__)->value.pair.first; \
  112. auto label(sfun,__LINE__) = Memory::create_lisp_object_cfunction(special); \
  113. create_arguments_from_lambda_list_and_inject(label(params,__LINE__)->value.pair.rest, label(sfun,__LINE__)); \
  114. if_error_log_location_and_return(nullptr); \
  115. label(sfun,__LINE__)->docstring = Memory::create_string(docs); \
  116. define_symbol(label(sym,__LINE__), label(sfun,__LINE__)); \
  117. label(sfun,__LINE__)->value.cFunction->body = []() -> Lisp_Object*
  118. #define define(def, docs) _define_helper(def, docs, false)
  119. #define define_special(def, docs) _define_helper(def, docs, true)
  120. #define in_caller_env fluid_let( \
  121. Globals::Current_Execution::envi_stack.next_index, \
  122. Globals::Current_Execution::envi_stack.next_index-1)
  123. /*
  124. * iterate over lisp vectors
  125. */
  126. #define for_lisp_vector(v) \
  127. if (!v); else \
  128. if (int it_index = 0); else \
  129. for (auto it = v->value.vector.data; \
  130. it_index < v->value.vector.length; \
  131. it=v->value.vector.data+(++it_index))
  132. /*
  133. * iterate over lisp lists
  134. */
  135. #define for_lisp_list(l) \
  136. if (!l); else \
  137. if (int it_index = 0); else \
  138. for (Lisp_Object* head = l, *it; \
  139. Memory::get_type(head) == Lisp_Object_Type::Pair && (it = head->value.pair.first); \
  140. head = head->value.pair.rest, ++it_index)