|
- // #define console_normal "\x1B[0m"
- // #define console_red "\x1B[31m"
- // #define console_green "\x1B[32m"
- // #define console_cyan "\x1B[36m"
-
- #define console_normal ""
- #define console_red ""
- #define console_green ""
- #define console_cyan ""
-
- enum struct Log_Level {
- None,
- Critical,
- Warning,
- Info,
- Debug,
- };
-
- Log_Level log_level = Log_Level::Debug;
-
- void log_message(Log_Level type, char* message) {
- if (type > log_level)
- return;
-
- char* prefix;
- switch (type) {
- case Log_Level::Critical: prefix = "CRITICAL"; break;
- case Log_Level::Warning: prefix = "WARNING"; break;
- case Log_Level::Info: prefix = "INFO"; break;
- case Log_Level::Debug: prefix = "DEBUG"; break;
- default: return;
- }
- printf("%s: %s\n",prefix, message);
- }
-
- void panic(char* message) {
- log_message(Log_Level::Critical, message);
- exit(1);
- }
-
- void print(Ast_Node* node) {
- switch (node->type) {
- case (Ast_Node_Type::Nil): {
- printf("nil");
- } break;
- case (Ast_Node_Type::T): {
- printf("t");
- } break;
- case (Ast_Node_Type::Number): {
- printf("%f", node->value.number->value);
- } break;
- case (Ast_Node_Type::String): {
- printf("\"%s\"", node->value.string->value);
- } break;
- case (Ast_Node_Type::Symbol): {
- printf("%s", node->value.symbol->identifier);
- } break;
- case (Ast_Node_Type::Keyword): {
- printf(":%s", node->value.keyword->identifier);
- } break;
- case (Ast_Node_Type::Function): {
- if (node->value.function->type == Function_Type::Lambda)
- printf("[lambda]");
- else if (node->value.function->type == Function_Type::Special_Lambda)
- printf("[special-lambda]");
- else if (node->value.function->type == Function_Type::Macro)
- printf("[macro]");
- else
- assert(false);
- } break;
- case (Ast_Node_Type::CFunction): {
- printf("[C-function]");
- } break;
- case (Ast_Node_Type::Pair): {
- Ast_Node* head = node;
- printf("(");
-
- // NOTE(Felix): We cold do a while true here, however in case
- // we want to print a broken list (for logging the error) we
- // should do mo checks.
- while (head) {
- print(head->value.pair->first);
- head = head->value.pair->rest;
- if (!head)
- return;
- if (head->type != Ast_Node_Type::Pair)
- break;
- printf(" ");
- }
-
- if (head->type != Ast_Node_Type::Nil) {
- printf(" . ");
- print(head);
- }
-
- printf(")");
- } break;
- }
- }
-
- // XXX(Felix): obv code dublicate
- void fprint(FILE* f, Ast_Node* node) {
- switch (node->type) {
- case (Ast_Node_Type::Nil): {
- fprintf(f, "nil");
- } break;
- case (Ast_Node_Type::T): {
- fprintf(f, "t");
- } break;
- case (Ast_Node_Type::Number): {
- fprintf(f, "%f", node->value.number->value);
- } break;
- case (Ast_Node_Type::String): {
- fprintf(f, "\"%s\"", node->value.string->value);
- } break;
- case (Ast_Node_Type::Symbol): {
- fprintf(f, "%s", node->value.symbol->identifier);
- } break;
- case (Ast_Node_Type::Keyword): {
- fprintf(f, ":%s", node->value.keyword->identifier);
- } break;
- case (Ast_Node_Type::Function): {
- if (node->value.function->type == Function_Type::Lambda)
- fprintf(f, "[lambda]");
- else if (node->value.function->type == Function_Type::Special_Lambda)
- fprintf(f, "[special-lambda]");
- else if (node->value.function->type == Function_Type::Macro)
- fprintf(f, "[macro]");
- else
- assert(false);
- } break;
- case (Ast_Node_Type::CFunction): {
- fprintf(f, "[C-function]");
- } break;
- case (Ast_Node_Type::Pair): {
- Ast_Node* head = node;
- fprintf(f, "(");
-
- // NOTE(Felix): We cold do a while true here, however in case
- // we want to print a broken list (for logging the error) we
- // should do mo checks.
- while (head) {
- fprint(f, head->value.pair->first);
- head = head->value.pair->rest;
- if (!head)
- return;
- if (head->type != Ast_Node_Type::Pair)
- break;
- fprintf(f, " ");
- }
-
- if (head->type != Ast_Node_Type::Nil) {
- fprintf(f, " . ");
- print(head);
- }
-
- fprintf(f, ")");
- } break;
- }
- }
-
- void print_error_location() {
- if (error->location) {
- printf("%s (line %d, position %d)",
- error->location->file,
- error->location->line,
- error->location->column);
- } else {
- printf("no source code location avaliable");
- }
- }
-
- void log_error() {
- printf("%s%s%s\n", console_red,
- Error_Type_to_string(error->type),
- console_normal);
- printf(" in: %s", console_cyan);
- print_error_location();
- printf("%s\n", console_normal);
- }
|