#define console_normal "\x1B[0m" #define console_red "\x1B[31m" #define console_green "\x1B[32m" #define console_cyan "\x1B[36m" typedef enum { Log_Level_None, Log_Level_Critical, Log_Level_Warning, Log_Level_Info, Log_Level_Debug, } Log_Level; 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; case Log_Level_None: return; } printf("%s: %s\n",prefix, message); } void panic(char* message) { log_message(Log_Level_Critical, message); exit(1); } char* Ast_Node_Type_to_string(Ast_Node_Type type) { switch (type) { case(Ast_Node_Type_Nil): return "nil"; case(Ast_Node_Type_Number): return "number"; case(Ast_Node_Type_String): return "string"; case(Ast_Node_Type_Symbol): return "symbol"; case(Ast_Node_Type_Keyword): return "keyword"; case(Ast_Node_Type_Function): return "function"; case(Ast_Node_Type_Built_In_Function): return "built-in function"; case(Ast_Node_Type_Pair): return "pair"; } } void print(Ast_Node* node) { switch (node->type) { case (Ast_Node_Type_Nil): { printf("nil"); } 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): { printf("[lambda]"); } break; case (Ast_Node_Type_Built_In_Function): { printf("[built-in-function %s]", node->value.built_in_function->identifier); } break; case (Ast_Node_Type_Pair): { Ast_Node* head = node; printf("("); while (1) { print(head->value.pair->first); head = head->value.pair->rest; if (head->type != Ast_Node_Type_Pair) break; printf(" "); } if (head->type != Ast_Node_Type_Nil) { printf(" . "); print(head); } printf(")"); } break; } } void log_error() { printf("\t%s%s%s\n", console_red, Error_Type_to_string(error->type), console_normal); printf("\t in: %s", console_cyan); print(error->location); printf("%s\n", console_normal); }