ArkScript
A small, fast, functional and scripting language for video games
Exceptions.hpp
Go to the documentation of this file.
1/**
2 * @file Exceptions.hpp
3 * @author Alexandre Plateau ([email protected]), Max ([email protected])
4 * @brief ArkScript homemade exceptions
5 * @date 2020-10-27
6 *
7 * @copyright Copyright (c) 2020-2025
8 *
9 */
10
11#ifndef INCLUDE_ARK_EXCEPTIONS_HPP
12#define INCLUDE_ARK_EXCEPTIONS_HPP
13
14#include <string>
15#include <utility>
16#include <vector>
17#include <stdexcept>
18#include <optional>
19#include <ostream>
20#include <iostream>
21
23#include <Ark/Platform.hpp>
24
25namespace Ark
26{
27 namespace internal
28 {
29 class Node;
30 }
31
32 class ARK_API Error : public std::runtime_error
33 {
34 public:
35 explicit Error(const std::string& message) :
36 std::runtime_error(message)
37 {}
38
39 [[nodiscard]] virtual std::string details(bool colorize [[maybe_unused]]) const
40 {
41 return what();
42 }
43 };
44
45 /**
46 * @brief A type error triggered when types don't match
47 *
48 */
49 class ARK_API TypeError final : public Error
50 {
51 public:
52 explicit TypeError(const std::string& message) :
53 Error(message)
54 {}
55 };
56
57 /**
58 * @brief An assertion error, only triggered from ArkScript code through (assert expr error-message)
59 *
60 */
61 class ARK_API AssertionFailed final : public Error
62 {
63 public:
64 explicit AssertionFailed(const std::string& message) :
65 Error("AssertionFailed: " + message)
66 {}
67 };
68
69 class ARK_API NestedError final : public Error
70 {
71 public:
72 NestedError(const Error& e, const std::string& details) :
73 Error("NestedError"),
74 m_details(e.details(/* colorize= */ false))
75 {
76 if (!m_details.empty() && m_details.back() != '\n')
77 m_details += '\n';
78 m_details += "\n" + details;
79 }
80
81 NestedError(const std::exception& e, const std::string& details) :
82 Error("NestedError"),
83 m_details(e.what())
84 {
85 if (!m_details.empty() && m_details.back() != '\n')
86 m_details += '\n';
87 m_details += "\n" + details;
88 }
89
90 [[nodiscard]] const char* what() const noexcept override
91 {
92 return m_details.c_str();
93 }
94
95 private:
96 std::string m_details;
97 };
98
100 {
101 const std::string filename;
102 const std::size_t line;
103 const std::size_t col;
104 const std::string expr;
105 const std::optional<internal::utf8_char_t> symbol;
106 const bool is_macro_expansion = false;
107
108 CodeErrorContext(std::string filename_, const std::size_t lineNum, const std::size_t column, std::string expression, const std::optional<internal::utf8_char_t> maybe_symbol = std::nullopt) :
109 filename(std::move(filename_)),
110 line(lineNum),
111 col(column),
112 expr(std::move(expression)),
113 symbol(maybe_symbol)
114 {}
115
116 CodeErrorContext(std::string filename_, const std::size_t lineNum, const std::size_t column, std::string expression, const bool from_macro_expansion) :
117 filename(std::move(filename_)),
118 line(lineNum),
119 col(column),
120 expr(std::move(expression)),
121 symbol(std::nullopt),
122 is_macro_expansion(from_macro_expansion)
123 {}
124 };
125
126 /**
127 * @brief CodeError thrown by the compiler (parser, macro processor, optimizer, and compiler itself)
128 *
129 */
130 struct ARK_API CodeError final : Error
131 {
133 const std::optional<CodeErrorContext> additional_context;
134
135 CodeError(const std::string& what, CodeErrorContext ctx, std::optional<CodeErrorContext> maybe_more_context = std::nullopt) :
136 Error(what),
137 context(std::move(ctx)),
138 additional_context(std::move(maybe_more_context))
139 {}
140 };
141
142 namespace Diagnostics
143 {
144 /**
145 * @brief Helper to create a colorized context to report errors to the user
146 *
147 * @param os stream in which the error will be written
148 * @param filename path to the file in which the error is
149 * @param expr optional expression causing the error
150 * @param sym_size length of expression to underline (can be 0)
151 * @param target_line line where the error is
152 * @param col_start where the error starts on the given line
153 * @param maybe_context optional context, parent of the error
154 * @param whole_line when true, underline the whole line, disregarding col_start and sym_size
155 * @param colorize generate colors or not
156 */
157 ARK_API void makeContext(
158 std::ostream& os,
159 const std::string& filename,
160 const std::optional<std::string>& expr,
161 std::size_t sym_size,
162 std::size_t target_line,
163 std::size_t col_start,
164 const std::optional<CodeErrorContext>& maybe_context,
165 bool whole_line,
166 bool colorize);
167
168 /**
169 * @brief Helper used by the compiler to generate a colorized context from a node
170 *
171 * @param message error message to be included in the context
172 * @param node AST node with the error
173 * @return std::string
174 */
175 ARK_API std::string makeContextWithNode(const std::string& message, const internal::Node& node);
176
177 /**
178 * @brief Generate a diagnostic from an error and print it to the standard output
179 *
180 * @param e code error
181 * @param os output stream
182 * @param colorize generate colors or not
183 */
184 ARK_API void generate(const CodeError& e, std::ostream& os = std::cout, bool colorize = true);
185 }
186}
187
188#endif
#define ARK_API
Definition Module.hpp:28
ArkScript configuration macros.
An assertion error, only triggered from ArkScript code through (assert expr error-message)
AssertionFailed(const std::string &message)
virtual std::string details(bool colorize) const
Error(const std::string &message)
NestedError(const Error &e, const std::string &details)
NestedError(const std::exception &e, const std::string &details)
const char * what() const noexcept override
std::string m_details
A type error triggered when types don't match.
TypeError(const std::string &message)
A node of an Abstract Syntax Tree for ArkScript.
Definition Node.hpp:30
ARK_API void generate(const CodeError &e, std::ostream &os=std::cout, bool colorize=true)
Generate a diagnostic from an error and print it to the standard output.
ARK_API std::string makeContextWithNode(const std::string &message, const internal::Node &node)
Helper used by the compiler to generate a colorized context from a node.
ARK_API void makeContext(std::ostream &os, const std::string &filename, const std::optional< std::string > &expr, std::size_t sym_size, std::size_t target_line, std::size_t col_start, const std::optional< CodeErrorContext > &maybe_context, bool whole_line, bool colorize)
Helper to create a colorized context to report errors to the user.
const std::size_t line
const std::string expr
const std::size_t col
CodeErrorContext(std::string filename_, const std::size_t lineNum, const std::size_t column, std::string expression, const std::optional< internal::utf8_char_t > maybe_symbol=std::nullopt)
const std::string filename
const std::optional< internal::utf8_char_t > symbol
CodeErrorContext(std::string filename_, const std::size_t lineNum, const std::size_t column, std::string expression, const bool from_macro_expansion)
CodeError thrown by the compiler (parser, macro processor, optimizer, and compiler itself)
const std::optional< CodeErrorContext > additional_context
const CodeErrorContext context
CodeError(const std::string &what, CodeErrorContext ctx, std::optional< CodeErrorContext > maybe_more_context=std::nullopt)