Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

181 строка
4.9 KiB

  1. // #define console_normal "\x1B[0m"
  2. // #define console_red "\x1B[31m"
  3. // #define console_green "\x1B[32m"
  4. // #define console_cyan "\x1B[36m"
  5. #define console_normal ""
  6. #define console_red ""
  7. #define console_green ""
  8. #define console_cyan ""
  9. enum struct Log_Level {
  10. None,
  11. Critical,
  12. Warning,
  13. Info,
  14. Debug,
  15. };
  16. Log_Level log_level = Log_Level::Debug;
  17. void log_message(Log_Level type, char* message) {
  18. if (type > log_level)
  19. return;
  20. char* prefix;
  21. switch (type) {
  22. case Log_Level::Critical: prefix = "CRITICAL"; break;
  23. case Log_Level::Warning: prefix = "WARNING"; break;
  24. case Log_Level::Info: prefix = "INFO"; break;
  25. case Log_Level::Debug: prefix = "DEBUG"; break;
  26. default: return;
  27. }
  28. printf("%s: %s\n",prefix, message);
  29. }
  30. void panic(char* message) {
  31. log_message(Log_Level::Critical, message);
  32. exit(1);
  33. }
  34. void print(Ast_Node* node) {
  35. switch (node->type) {
  36. case (Ast_Node_Type::Nil): {
  37. printf("nil");
  38. } break;
  39. case (Ast_Node_Type::T): {
  40. printf("t");
  41. } break;
  42. case (Ast_Node_Type::Number): {
  43. printf("%f", node->value.number->value);
  44. } break;
  45. case (Ast_Node_Type::String): {
  46. printf("\"%s\"", node->value.string->value);
  47. } break;
  48. case (Ast_Node_Type::Symbol): {
  49. printf("%s", node->value.symbol->identifier);
  50. } break;
  51. case (Ast_Node_Type::Keyword): {
  52. printf(":%s", node->value.keyword->identifier);
  53. } break;
  54. case (Ast_Node_Type::Function): {
  55. if (node->value.function->type == Function_Type::Lambda)
  56. printf("[lambda]");
  57. else if (node->value.function->type == Function_Type::Special_Lambda)
  58. printf("[special-lambda]");
  59. else if (node->value.function->type == Function_Type::Macro)
  60. printf("[macro]");
  61. else
  62. assert(false);
  63. } break;
  64. case (Ast_Node_Type::CFunction): {
  65. printf("[C-function]");
  66. } break;
  67. case (Ast_Node_Type::Pair): {
  68. Ast_Node* head = node;
  69. printf("(");
  70. // NOTE(Felix): We cold do a while true here, however in case
  71. // we want to print a broken list (for logging the error) we
  72. // should do mo checks.
  73. while (head) {
  74. print(head->value.pair->first);
  75. head = head->value.pair->rest;
  76. if (!head)
  77. return;
  78. if (head->type != Ast_Node_Type::Pair)
  79. break;
  80. printf(" ");
  81. }
  82. if (head->type != Ast_Node_Type::Nil) {
  83. printf(" . ");
  84. print(head);
  85. }
  86. printf(")");
  87. } break;
  88. }
  89. }
  90. // XXX(Felix): obv code dublicate
  91. void fprint(FILE* f, Ast_Node* node) {
  92. switch (node->type) {
  93. case (Ast_Node_Type::Nil): {
  94. fprintf(f, "nil");
  95. } break;
  96. case (Ast_Node_Type::T): {
  97. fprintf(f, "t");
  98. } break;
  99. case (Ast_Node_Type::Number): {
  100. fprintf(f, "%f", node->value.number->value);
  101. } break;
  102. case (Ast_Node_Type::String): {
  103. fprintf(f, "\"%s\"", node->value.string->value);
  104. } break;
  105. case (Ast_Node_Type::Symbol): {
  106. fprintf(f, "%s", node->value.symbol->identifier);
  107. } break;
  108. case (Ast_Node_Type::Keyword): {
  109. fprintf(f, ":%s", node->value.keyword->identifier);
  110. } break;
  111. case (Ast_Node_Type::Function): {
  112. if (node->value.function->type == Function_Type::Lambda)
  113. fprintf(f, "[lambda]");
  114. else if (node->value.function->type == Function_Type::Special_Lambda)
  115. fprintf(f, "[special-lambda]");
  116. else if (node->value.function->type == Function_Type::Macro)
  117. fprintf(f, "[macro]");
  118. else
  119. assert(false);
  120. } break;
  121. case (Ast_Node_Type::CFunction): {
  122. fprintf(f, "[C-function]");
  123. } break;
  124. case (Ast_Node_Type::Pair): {
  125. Ast_Node* head = node;
  126. fprintf(f, "(");
  127. // NOTE(Felix): We cold do a while true here, however in case
  128. // we want to print a broken list (for logging the error) we
  129. // should do mo checks.
  130. while (head) {
  131. fprint(f, head->value.pair->first);
  132. head = head->value.pair->rest;
  133. if (!head)
  134. return;
  135. if (head->type != Ast_Node_Type::Pair)
  136. break;
  137. fprintf(f, " ");
  138. }
  139. if (head->type != Ast_Node_Type::Nil) {
  140. fprintf(f, " . ");
  141. print(head);
  142. }
  143. fprintf(f, ")");
  144. } break;
  145. }
  146. }
  147. void print_error_location() {
  148. if (error->location) {
  149. printf("%s (line %d, position %d)",
  150. error->location->file,
  151. error->location->line,
  152. error->location->column);
  153. } else {
  154. printf("no source code location avaliable");
  155. }
  156. }
  157. void log_error() {
  158. printf("%s%s%s\n", console_red,
  159. Error_Type_to_string(error->type),
  160. console_normal);
  161. printf(" in: %s", console_cyan);
  162. print_error_location();
  163. printf("%s\n", console_normal);
  164. }