Rename to and remove cleanup the source tree for errors
This commit is contained in:
parent
4605e22e68
commit
a215eb6cd9
|
@ -19,9 +19,11 @@
|
||||||
#ifndef SERENE_ERRORS_H
|
#ifndef SERENE_ERRORS_H
|
||||||
#define SERENE_ERRORS_H
|
#define SERENE_ERRORS_H
|
||||||
|
|
||||||
#include "serene/errors/base.h"
|
|
||||||
#include "serene/errors/errc.h"
|
|
||||||
#include "serene/export.h"
|
#include "serene/export.h"
|
||||||
|
#include "serene/reader/location.h"
|
||||||
|
|
||||||
|
#define GET_CLASS_DEFS
|
||||||
|
#include "serene/errors/errs.h.inc"
|
||||||
|
|
||||||
#include <llvm/Support/Casting.h>
|
#include <llvm/Support/Casting.h>
|
||||||
#include <llvm/Support/Error.h>
|
#include <llvm/Support/Error.h>
|
||||||
|
@ -32,6 +34,33 @@ class SereneContext;
|
||||||
|
|
||||||
namespace serene::errors {
|
namespace serene::errors {
|
||||||
|
|
||||||
|
class SERENE_EXPORT SereneError : public llvm::ErrorInfo<SereneError> {
|
||||||
|
public:
|
||||||
|
static char ID;
|
||||||
|
ErrorType errorType;
|
||||||
|
|
||||||
|
SereneContext &ctx;
|
||||||
|
reader::LocationRange location;
|
||||||
|
std::string msg;
|
||||||
|
|
||||||
|
void log(llvm::raw_ostream &os) const override { os << msg; }
|
||||||
|
|
||||||
|
std::error_code convertToErrorCode() const override {
|
||||||
|
// TODO: Fix this by creating a mapping from ErrorType to standard
|
||||||
|
// errc or return the ErrorType number instead
|
||||||
|
return std::make_error_code(std::errc::io_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
SereneError(SereneContext &ctx, ErrorType errtype, reader::LocationRange &loc)
|
||||||
|
: errorType(errtype), ctx(ctx), location(loc){};
|
||||||
|
|
||||||
|
SereneError(SereneContext &ctx, ErrorType errtype, reader::LocationRange &loc,
|
||||||
|
llvm::StringRef msg)
|
||||||
|
: errorType(errtype), ctx(ctx), location(loc), msg(msg.str()){};
|
||||||
|
|
||||||
|
reader::LocationRange &where() { return location; };
|
||||||
|
};
|
||||||
|
|
||||||
/// Create and return a Serene flavored `llvm::Error` by passing the parameters
|
/// Create and return a Serene flavored `llvm::Error` by passing the parameters
|
||||||
/// directly to the constructor of type `E`.
|
/// directly to the constructor of type `E`.
|
||||||
///
|
///
|
||||||
|
@ -39,7 +68,8 @@ namespace serene::errors {
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
SERENE_EXPORT llvm::Error makeError(SereneContext &ctx, ErrorType errtype,
|
SERENE_EXPORT llvm::Error makeError(SereneContext &ctx, ErrorType errtype,
|
||||||
Args &&...args) {
|
Args &&...args) {
|
||||||
return llvm::make_error<Error>(ctx, errtype, std::forward<Args>(args)...);
|
return llvm::make_error<SereneError>(ctx, errtype,
|
||||||
|
std::forward<Args>(args)...);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Returns the messange that the given error \p e is holding. It doesn't cast
|
/// Returns the messange that the given error \p e is holding. It doesn't cast
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
/* -*- C++ -*-
|
|
||||||
* Serene Programming Language
|
|
||||||
*
|
|
||||||
* Copyright (c) 2019-2022 Sameer Rahmani <lxsameer@gnu.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, version 2.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SERENE_ERRORS_BASE_H
|
|
||||||
#define SERENE_ERRORS_BASE_H
|
|
||||||
|
|
||||||
#include "serene/export.h"
|
|
||||||
#include "serene/reader/location.h"
|
|
||||||
|
|
||||||
#define GET_CLASS_DEFS
|
|
||||||
#include "serene/errors/errs.h.inc"
|
|
||||||
|
|
||||||
#include <system_error>
|
|
||||||
|
|
||||||
#include <llvm/Support/Error.h>
|
|
||||||
#include <llvm/Support/FormatVariadic.h>
|
|
||||||
|
|
||||||
namespace serene::errors {
|
|
||||||
|
|
||||||
class SERENE_EXPORT Error : public llvm::ErrorInfo<Error> {
|
|
||||||
public:
|
|
||||||
static char ID;
|
|
||||||
ErrorType errorType;
|
|
||||||
|
|
||||||
SereneContext &ctx;
|
|
||||||
reader::LocationRange location;
|
|
||||||
std::string msg;
|
|
||||||
|
|
||||||
void log(llvm::raw_ostream &os) const override { os << msg; }
|
|
||||||
|
|
||||||
std::error_code convertToErrorCode() const override {
|
|
||||||
// TODO: Fix this by creating a mapping from ErrorType to standard
|
|
||||||
// errc or return the ErrorType number instead
|
|
||||||
return std::make_error_code(std::errc::io_error);
|
|
||||||
}
|
|
||||||
|
|
||||||
Error(SereneContext &ctx, ErrorType errtype, reader::LocationRange &loc)
|
|
||||||
: errorType(errtype), ctx(ctx), location(loc){};
|
|
||||||
|
|
||||||
Error(SereneContext &ctx, ErrorType errtype, reader::LocationRange &loc,
|
|
||||||
llvm::StringRef msg)
|
|
||||||
: errorType(errtype), ctx(ctx), location(loc), msg(msg.str()){};
|
|
||||||
|
|
||||||
reader::LocationRange &where() { return location; };
|
|
||||||
};
|
|
||||||
|
|
||||||
}; // namespace serene::errors
|
|
||||||
#endif
|
|
|
@ -1,124 +0,0 @@
|
||||||
/* -*- C++ -*-
|
|
||||||
* Serene Programming Language
|
|
||||||
*
|
|
||||||
* Copyright (c) 2019-2022 Sameer Rahmani <lxsameer@gnu.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, version 2.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SERENE_ERRORS_CONSTANTS_H
|
|
||||||
#define SERENE_ERRORS_CONSTANTS_H
|
|
||||||
|
|
||||||
#include <llvm/Support/FormatVariadic.h>
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace serene {
|
|
||||||
namespace errors {
|
|
||||||
|
|
||||||
/// This enum represent the expression type and **not** the value type.
|
|
||||||
enum class ErrType {
|
|
||||||
Syntax,
|
|
||||||
Semantic,
|
|
||||||
Compile,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ErrID {
|
|
||||||
E0000 = 0,
|
|
||||||
E0001,
|
|
||||||
E0002,
|
|
||||||
E0003,
|
|
||||||
E0004,
|
|
||||||
E0005,
|
|
||||||
E0006,
|
|
||||||
E0007,
|
|
||||||
E0008,
|
|
||||||
E0009,
|
|
||||||
E0010,
|
|
||||||
E0011,
|
|
||||||
E0012,
|
|
||||||
E0013,
|
|
||||||
E0014,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ErrorVariant {
|
|
||||||
ErrID id;
|
|
||||||
|
|
||||||
std::string description;
|
|
||||||
std::string longDescription;
|
|
||||||
|
|
||||||
ErrorVariant(ErrID id, std::string desc, std::string longDesc)
|
|
||||||
: id(id), description(std::move(desc)),
|
|
||||||
longDescription(std::move(longDesc)){};
|
|
||||||
|
|
||||||
std::string getErrId() { return llvm::formatv("E{0:d}", id); };
|
|
||||||
};
|
|
||||||
|
|
||||||
static ErrorVariant
|
|
||||||
UnknownError(E0000, "Can't find any description for this error.", "");
|
|
||||||
static ErrorVariant
|
|
||||||
DefExpectSymbol(E0001, "The first argument to 'def' has to be a Symbol.",
|
|
||||||
"");
|
|
||||||
|
|
||||||
static ErrorVariant DefWrongNumberOfArgs(
|
|
||||||
E0002, "Wrong number of arguments is passed to the 'def' form.", "");
|
|
||||||
|
|
||||||
static ErrorVariant FnNoArgsList(E0003, "'fn' form requires an argument list.",
|
|
||||||
"");
|
|
||||||
|
|
||||||
static ErrorVariant FnArgsMustBeList(E0004, "'fn' arguments should be a list.",
|
|
||||||
"");
|
|
||||||
|
|
||||||
static ErrorVariant CantResolveSymbol(E0005, "Can't resolve the given name.",
|
|
||||||
"");
|
|
||||||
static ErrorVariant
|
|
||||||
DontKnowHowToCallNode(E0006, "Don't know how to call the given expression.",
|
|
||||||
"");
|
|
||||||
|
|
||||||
static ErrorVariant PassFailureError(E0007, "Pass Failure.", "");
|
|
||||||
|
|
||||||
static ErrorVariant NSLoadError(E0008, "Faild to find a namespace.", "");
|
|
||||||
|
|
||||||
static ErrorVariant
|
|
||||||
NSAddToSMError(E0009, "Faild to add the namespace to the source manager.",
|
|
||||||
"");
|
|
||||||
|
|
||||||
static ErrorVariant
|
|
||||||
EOFWhileScaningAList(E0010, "EOF reached before closing of list", "");
|
|
||||||
|
|
||||||
static ErrorVariant InvalidDigitForNumber(E0011, "Invalid digit for a number.",
|
|
||||||
"");
|
|
||||||
|
|
||||||
static ErrorVariant
|
|
||||||
TwoFloatPoints(E0012, "Two or more float point characters in a number", "");
|
|
||||||
|
|
||||||
static ErrorVariant
|
|
||||||
InvalidCharacterForSymbol(E0013, "Invalid character for a symbol", "");
|
|
||||||
|
|
||||||
static ErrorVariant CompilationError(E0014, "Compilation error!", "");
|
|
||||||
|
|
||||||
static std::map<ErrID, ErrorVariant *> ErrDesc = {
|
|
||||||
{E0000, &UnknownError}, {E0001, &DefExpectSymbol},
|
|
||||||
{E0002, &DefWrongNumberOfArgs}, {E0003, &FnNoArgsList},
|
|
||||||
{E0004, &FnArgsMustBeList}, {E0005, &CantResolveSymbol},
|
|
||||||
{E0006, &DontKnowHowToCallNode}, {E0007, &PassFailureError},
|
|
||||||
{E0008, &NSLoadError}, {E0009, &NSAddToSMError},
|
|
||||||
{E0010, &EOFWhileScaningAList}, {E0011, &InvalidDigitForNumber},
|
|
||||||
{E0012, &TwoFloatPoints}, {E0013, &InvalidCharacterForSymbol},
|
|
||||||
{E0014, &CompilationError}};
|
|
||||||
|
|
||||||
} // namespace errors
|
|
||||||
} // namespace serene
|
|
||||||
#endif
|
|
|
@ -1,77 +0,0 @@
|
||||||
/* -*- C++ -*-
|
|
||||||
* Serene Programming Language
|
|
||||||
*
|
|
||||||
* Copyright (c) 2019-2022 Sameer Rahmani <lxsameer@gnu.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, version 2.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SERENE_ERRORS_ERRC_H
|
|
||||||
#define SERENE_ERRORS_ERRC_H
|
|
||||||
|
|
||||||
#include <llvm/Support/Errc.h>
|
|
||||||
|
|
||||||
namespace serene {
|
|
||||||
|
|
||||||
/// A collection of common error codes in Serene
|
|
||||||
enum class errc {
|
|
||||||
argument_list_too_long = int(std::errc::argument_list_too_long),
|
|
||||||
argument_out_of_domain = int(std::errc::argument_out_of_domain),
|
|
||||||
bad_address = int(std::errc::bad_address),
|
|
||||||
bad_file_descriptor = int(std::errc::bad_file_descriptor),
|
|
||||||
broken_pipe = int(std::errc::broken_pipe),
|
|
||||||
device_or_resource_busy = int(std::errc::device_or_resource_busy),
|
|
||||||
directory_not_empty = int(std::errc::directory_not_empty),
|
|
||||||
executable_format_error = int(std::errc::executable_format_error),
|
|
||||||
file_exists = int(std::errc::file_exists),
|
|
||||||
file_too_large = int(std::errc::file_too_large),
|
|
||||||
filename_too_long = int(std::errc::filename_too_long),
|
|
||||||
function_not_supported = int(std::errc::function_not_supported),
|
|
||||||
illegal_byte_sequence = int(std::errc::illegal_byte_sequence),
|
|
||||||
inappropriate_io_control_operation =
|
|
||||||
int(std::errc::inappropriate_io_control_operation),
|
|
||||||
interrupted = int(std::errc::interrupted),
|
|
||||||
invalid_argument = int(std::errc::invalid_argument),
|
|
||||||
invalid_seek = int(std::errc::invalid_seek),
|
|
||||||
io_error = int(std::errc::io_error),
|
|
||||||
is_a_directory = int(std::errc::is_a_directory),
|
|
||||||
no_child_process = int(std::errc::no_child_process),
|
|
||||||
no_lock_available = int(std::errc::no_lock_available),
|
|
||||||
no_space_on_device = int(std::errc::no_space_on_device),
|
|
||||||
no_such_device_or_address = int(std::errc::no_such_device_or_address),
|
|
||||||
no_such_device = int(std::errc::no_such_device),
|
|
||||||
no_such_file_or_directory = int(std::errc::no_such_file_or_directory),
|
|
||||||
no_such_process = int(std::errc::no_such_process),
|
|
||||||
not_a_directory = int(std::errc::not_a_directory),
|
|
||||||
not_enough_memory = int(std::errc::not_enough_memory),
|
|
||||||
not_supported = int(std::errc::not_supported),
|
|
||||||
operation_not_permitted = int(std::errc::operation_not_permitted),
|
|
||||||
permission_denied = int(std::errc::permission_denied),
|
|
||||||
read_only_file_system = int(std::errc::read_only_file_system),
|
|
||||||
resource_deadlock_would_occur = int(std::errc::resource_deadlock_would_occur),
|
|
||||||
resource_unavailable_try_again =
|
|
||||||
int(std::errc::resource_unavailable_try_again),
|
|
||||||
result_out_of_range = int(std::errc::result_out_of_range),
|
|
||||||
too_many_files_open_in_system = int(std::errc::too_many_files_open_in_system),
|
|
||||||
too_many_files_open = int(std::errc::too_many_files_open),
|
|
||||||
too_many_links = int(std::errc::too_many_links)
|
|
||||||
};
|
|
||||||
|
|
||||||
/// The **official way** to create `std::error_code` in context of Serene.
|
|
||||||
inline std::error_code make_error_code(errc E) {
|
|
||||||
return std::error_code(static_cast<int>(E), std::generic_category());
|
|
||||||
};
|
|
||||||
|
|
||||||
}; // namespace serene
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -18,15 +18,13 @@
|
||||||
|
|
||||||
#include "serene/errors.h"
|
#include "serene/errors.h"
|
||||||
|
|
||||||
#include "serene/errors/base.h"
|
|
||||||
|
|
||||||
#include <llvm/Support/Casting.h>
|
#include <llvm/Support/Casting.h>
|
||||||
#include <llvm/Support/Error.h>
|
#include <llvm/Support/Error.h>
|
||||||
|
|
||||||
namespace serene::errors {
|
namespace serene::errors {
|
||||||
|
|
||||||
// We need this to make Error class a llvm::Error friendy implementation
|
// We need this to make Error class a llvm::Error friendy implementation
|
||||||
char Error::ID;
|
char SereneError::ID;
|
||||||
|
|
||||||
std::string getMessage(const llvm::Error &e) {
|
std::string getMessage(const llvm::Error &e) {
|
||||||
std::string msg;
|
std::string msg;
|
||||||
|
|
|
@ -38,14 +38,15 @@ TEST_CASE("Serene Error construction", "[errors]") {
|
||||||
auto ctx = makeSereneContext();
|
auto ctx = makeSereneContext();
|
||||||
llvm::Error err = makeError(*ctx, PassFailureError, *range, "test error");
|
llvm::Error err = makeError(*ctx, PassFailureError, *range, "test error");
|
||||||
|
|
||||||
auto unhandled = llvm::handleErrors(std::move(err), [&](const Error &e) {
|
auto unhandled =
|
||||||
REQUIRE(e.message() == "test error");
|
llvm::handleErrors(std::move(err), [&](const SereneError &e) {
|
||||||
const auto *v = getVariant(e.errorType);
|
REQUIRE(e.message() == "test error");
|
||||||
REQUIRE(v != nullptr);
|
const auto *v = getVariant(e.errorType);
|
||||||
CHECK(v->title == "PassFailureError");
|
REQUIRE(v != nullptr);
|
||||||
CHECK(v->desc == "Pass Failure.");
|
CHECK(v->title == "PassFailureError");
|
||||||
CHECK(v->help.empty());
|
CHECK(v->desc == "Pass Failure.");
|
||||||
});
|
CHECK(v->help.empty());
|
||||||
|
});
|
||||||
|
|
||||||
CHECK(!unhandled);
|
CHECK(!unhandled);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,9 +30,9 @@
|
||||||
// `llvm::Error`s has to be checked in the same scope. This macro makes
|
// `llvm::Error`s has to be checked in the same scope. This macro makes
|
||||||
// the check easy while were testing the other aspects of the error.
|
// the check easy while were testing the other aspects of the error.
|
||||||
// `t` is the concrete error type and `e` is the error instance.
|
// `t` is the concrete error type and `e` is the error instance.
|
||||||
#define CHECK_ERR(t, e) \
|
#define CHECK_ERR(t, e) \
|
||||||
auto unhandled = \
|
auto unhandled = llvm::handleErrors( \
|
||||||
llvm::handleErrors(e, [&](const Error &x) { CHECK(x.errorType == t); }); \
|
e, [&](const SereneError &x) { CHECK(x.errorType == t); }); \
|
||||||
CHECK(!unhandled);
|
CHECK(!unhandled);
|
||||||
|
|
||||||
namespace serene {
|
namespace serene {
|
||||||
|
|
Loading…
Reference in New Issue