tan  0.0.1
error.cpp
1 #include "base/error.h"
2 #include "source_file/token.h"
3 #include "backtrace/tan_backtrace.h"
4 #include <fmt/core.h>
5 
6 using namespace tanlang;
7 
8 [[noreturn]] void __tan_assert_fail(const char *expr, const char *file, size_t lineno) {
9  print_back_trace();
10  Error(ErrorType::ASSERTION_FAILED,
11  fmt::format("ASSERTION FAILED: {}\nat {}:{}\n", expr, file, std::to_string(lineno)))
12  .raise();
13 }
14 
15 CompileException::CompileException(ErrorType error_type, const str &msg) : std::runtime_error(msg), _type(error_type) {}
16 
17 CompileException::CompileException(ErrorType error_type, const char *msg)
18  : std::runtime_error(msg), _type(error_type) {}
19 
20 ErrorType CompileException::type() const { return _type; }
21 
22 Error::Error(const str &error_message) { _msg = "[ERROR] " + error_message; }
23 
24 Error::Error(ErrorType type, const str &error_message) : _type(type) {
25  _msg = fmt::format("[{}] {}", ERROR_TYPE_ENUM_TO_STRING[type], error_message);
26 }
27 
28 Error::Error(ErrorType type, SourceSpan span, const str &error_message) : _type(type) {
29  SourceFile *src = span.src();
30  _msg = fmt::format(
31  "[{}] in {}:{} {}\n", ERROR_TYPE_ENUM_TO_STRING[type], src->get_filename(), span.start().l, error_message);
32 
33  uint32_t col = span.start().c;
34  for (uint32_t line = span.start().l; line <= span.end().l; ++line) {
35  str src_line = src->get_line(line);
36 
37  str indent = col > 0 ? str(col, ' ') : "";
38 
39  uint32_t end_col = (uint32_t)src_line.length(); // exclusive
40  if (line == span.end().l) {
41  end_col = span.end().c + 1;
42  }
43  str indicator = str(end_col - col, '^');
44 
45  _msg += fmt::format("{}\n{}{}\n", src_line, indent, indicator);
46 
47  col = 0;
48  }
49 }
50 
51 Error::Error(ErrorType type, Token *start, Token *end, const str &error_message)
52  : Error(type, Token::GetSourceSpan(*start, *end), error_message) {}
53 
54 void Error::raise() const { throw CompileException(type(), _msg); }
55 
56 ErrorType Error::type() const { return _type; }
57 
58 #define ERROR_TYPE_TO_STRING_HELPER(x) \
59  { ErrorType::x, #x }
60 
61 umap<ErrorType, str> Error::ERROR_TYPE_ENUM_TO_STRING{
62  ERROR_TYPE_TO_STRING_HELPER(GENERIC_ERROR),
63  ERROR_TYPE_TO_STRING_HELPER(ASSERTION_FAILED),
64  ERROR_TYPE_TO_STRING_HELPER(FILE_NOT_FOUND),
65  ERROR_TYPE_TO_STRING_HELPER(SYNTAX_ERROR),
66  ERROR_TYPE_TO_STRING_HELPER(NOT_IMPLEMENTED),
67  ERROR_TYPE_TO_STRING_HELPER(SEMANTIC_ERROR),
68  ERROR_TYPE_TO_STRING_HELPER(UNKNOWN_SYMBOL),
69  ERROR_TYPE_TO_STRING_HELPER(IMPORT_ERROR),
70  ERROR_TYPE_TO_STRING_HELPER(TYPE_ERROR),
71  ERROR_TYPE_TO_STRING_HELPER(COMPILE_ERROR),
72  ERROR_TYPE_TO_STRING_HELPER(LINK_ERROR),
73 };
str get_line(size_t index) const
Return source at a specific line.
A span of source code tokens, inclusive on both ends.
Definition: source_file.h:96