Error* error;

proc delete_error() -> void {
    if (error) {
        free(error);
        error = nullptr;
    }
}

proc create_error(Error_Type type, Source_Code_Location* location) -> void {
    delete_error();
    debug_break();

    error = new(Error);
    error->type = type;
    error->location = location;
}

proc Error_Type_to_string(Error_Type type) -> const char* {
    switch (type) {
    case Error_Type::Assertion_Error:           return "Assertion failed";
    case Error_Type::File_Not_Found:            return "File not found";
    case Error_Type::Ill_Formed_Arguments:      return "Evaluation-error: Ill formed arguments";
    case Error_Type::Ill_Formed_Lambda_List:    return "Evaluation-error: Ill formed lambda list";
    case Error_Type::Ill_Formed_List:           return "Evaluation-error: Ill formed list";
    case Error_Type::Not_A_Function:            return "Evaluation-error: Not a function";
    case Error_Type::Not_Yet_Implemented:       return "Evaluation-error: Not yet implemented";
    case Error_Type::Symbol_Not_Defined:        return "Evaluation-error: Symbol not defined";
    case Error_Type::Syntax_Error:              return "Syntax Error";
    case Error_Type::Trailing_Garbage:          return "Evaluation-error: Trailing garbage following expression";
    case Error_Type::Type_Missmatch:            return "Evaluation-error: Type Missmatch";
    case Error_Type::Unbalanced_Parenthesis:    return "Parsing-error: Unbalanced parenthesis";
    case Error_Type::Unexpected_Eof:            return "Parsing-error: Unexpected EOF";
    case Error_Type::Unknown_Keyword_Argument:  return "Evaluation-error: Unknown keyword argument";
    case Error_Type::Wrong_Number_Of_Arguments: return "Evaluation-error: Wrong number of arguments";
    case Error_Type::Out_Of_Memory:             return "Runtime-error: Out of memory";
    default:                                    return "this error type doesn't have a desciption..";
    }
}

proc assert_type(Lisp_Object* node, Lisp_Object_Type type) -> void {
        if (!node)
            create_error(Error_Type::Unknown_Error, nullptr);
        if (node->type == type) return;
        create_error(Error_Type::Type_Missmatch, node->sourceCodeLocation);
}
