#ifndef ERROR_H_INCLUDED_ #define ERROR_H_INCLUDED_ #include #include #include #include #include #include enum class ec : unsigned { unknown =0, internal, no_feature, //section 1: system errors //section 2: YAML errors //section 3: noderef syntax errors //section 4: template string errors (parse time) p_internal =400, bad_format, blank_fname, invalid_fname, call_arg, eos =405, extra_rp, extra_lp, extra_p, extra_ab, extra_h =410, extra_c, early_close, escape_nostr, overmarked_arg, invalid_raw = 415, no_function, //section 5: template evaluation errors e_internal =500, bad_arg_type, bad_arg_rank, bad_randspec, invoke_null, invoke_type =505, node_bad_cvt, unpaired_args, too_many_args, not_enough_args, e_nonode =510, range_error, bad_math, m_divzero, //section 6: transformation errors t_internal =600, }; const std::map err_strs { //E0 {ec::unknown, "Unknown error."}, {ec::internal, "Internal error."}, {ec::no_feature, "Feature not implemented yet."}, //E400 {ec::p_internal, "Internal error in parser."}, {ec::bad_format, "Invalid argref."}, {ec::blank_fname, "Function names cannot be blank."}, {ec::invalid_fname, "Invalid character in function name."}, {ec::call_arg, "Arguments cannot be used as functions."}, //E405 {ec::eos, "Unexpected end-of-input"}, {ec::extra_rp, "Unmatched )."}, {ec::extra_lp, "Unmatched (; or unexpected >."}, {ec::extra_p, "Unexpected top-level |."}, {ec::extra_ab, "unescaped < in template context."}, //E410 {ec::extra_h, "encountered unexpected # in argument context."}, {ec::extra_c, "encountered unexpected characters after )."}, {ec::early_close, "blank argref is invalid."}, {ec::escape_nostr, "escape sequence outside of string context."}, {ec::overmarked_arg, "Argrefs at topmost level do not need #."}, //E415 {ec::invalid_raw, "Invalid raw string syntax."}, {ec::no_function, "No function by this name exists."}, //E500 {ec::e_internal, "Internal error in template evaluator."}, {ec::bad_arg_type, "Template function received argument of incorrect type."}, {ec::bad_arg_rank, "Template function received a list when it expected a single element."}, {ec::bad_randspec, "Bad parameters for a random function."}, {ec::invoke_null, "Invoke requires arguments."}, //E505 {ec::invoke_type, "The first argument to invoke must be a string, not a list."}, {ec::node_bad_cvt, "A synthesized node cannot be converted to another type."}, {ec::unpaired_args, "Template function expected arguments in sets, but could not complete a set."}, {ec::too_many_args, "Template function received more arguments than it expected."}, {ec::not_enough_args, "Template function did not receive all expected arguments."}, //E510 {ec::e_nonode, "'node' function's argument does not name a node"}, {ec::range_error, "? or [] index out of range."}, {ec::bad_math, "Invalid mathematical expression."}, {ec::m_divzero, "Division by zero occurred."}, //E500 {ec::t_internal, "Internal error in transformation processor"}, }; inline std::string format_err(ec err) { std::ostringstream out; out<<'E'<(err)<<": "<(desc)) , l2(std::make_shared(context)) , l3(std::make_shared(loc)) , l4(std::make_shared(info)) , c(ec::unknown) {} wordgen_error(ec err, const std::string& context, const std::string& loc, const std::string& info) : std::runtime_error(kblib::concat(format_err(err), context, loc, info)) , l1(std::make_shared(format_err(err))) , l2(std::make_shared(context)) , l3(std::make_shared(loc)) , l4(std::make_shared(info)) , c(err) {} std::shared_ptr l1, l2, l3, l4; ec c; ec code() const {return c;} }; inline bool operator==(const wordgen_error& l, const wordgen_error& r) { return l.what() == r.what(); } inline bool operator!=(const wordgen_error& l, const wordgen_error& r) { return l.what() != r.what(); } [[noreturn]] inline void parse_error(ec err, std::string_view str, const char* epos, std::string msg = "") { auto printable = kblib::escapify(str); auto index = kblib::calculate_translated_index(str, epos); throw wordgen_error( err, kblib::concat("\"", printable, "\"\n"), kblib::concat(" ", kblib::repeat(' ', index), "^\n"), std::move(msg)); } [[noreturn]] inline void parse_error(ec err, std::string_view str, long long epos, std::string msg = "") { parse_error(err, str, str.data() + epos, std::move(msg)); } #endif //ERROR_H_INCLUDED_