7#include <fmt/ostream.h>
26 return c ==
'(' || c ==
')' || c ==
'[' || c ==
']' || c ==
'{' || c ==
'}';
32 constexpr std::array pairing_color {
33 fmt::color::light_blue,
34 fmt::color::light_green,
35 fmt::color::light_salmon,
36 fmt::color::light_yellow,
37 fmt::color::light_cyan,
38 fmt::color::light_coral
41 constexpr std::size_t pairing_color_size = pairing_color.size();
43 for (
const char& c : line)
47 std::size_t pairing_color_index = 0;
52 pairing_color_index =
static_cast<std::size_t
>(std::abs(line_color_context_counts.
open_parentheses)) % pairing_color_size;
57 pairing_color_index =
static_cast<std::size_t
>(std::abs(line_color_context_counts.
open_parentheses)) % pairing_color_size;
60 pairing_color_index =
static_cast<std::size_t
>(std::abs(line_color_context_counts.
open_square_braces)) % pairing_color_size;
65 pairing_color_index =
static_cast<std::size_t
>(std::abs(line_color_context_counts.
open_square_braces)) % pairing_color_size;
68 pairing_color_index =
static_cast<std::size_t
>(std::abs(line_color_context_counts.
open_curly_braces)) % pairing_color_size;
73 pairing_color_index =
static_cast<std::size_t
>(std::abs(line_color_context_counts.
open_curly_braces)) % pairing_color_size;
79 fmt::print(ss,
"{}", fmt::styled(c, fmt::fg(pairing_color[pairing_color_index])));
82 fmt::print(ss,
"{}", c);
86 void makeContext(std::ostream& os,
const std::string& code,
const std::size_t target_line,
const std::size_t col_start,
const std::size_t sym_size,
const bool colorize)
91 if (target_line >= ctx.size())
94 const std::size_t first_line = target_line >= 3 ? target_line - 3 : 0;
95 const std::size_t last_line = (target_line + 3) <= ctx.size() ? target_line + 3 : ctx.size();
96 std::size_t overflow = (col_start + sym_size < ctx[target_line].size()) ? 0 : col_start + sym_size - ctx[target_line].size();
99 for (
auto i = first_line; i < last_line; ++i)
101 fmt::print(os,
"{: >5} |{}", i + 1, !ctx[i].empty() ?
" " :
"");
105 fmt::print(os,
"{}", ctx[i]);
106 fmt::print(os,
"\n");
108 if (i == target_line || (i > target_line && overflow > 0))
110 fmt::print(os,
" |");
112 const std::size_t curr_col_start = (overflow == 0) ? col_start : 0;
114 const std::size_t col_end = (i == target_line) ? std::min<std::size_t>(col_start + sym_size, ctx[target_line].size())
115 : std::min<std::size_t>(overflow, ctx[i].size());
117 overflow = (overflow > ctx[i].size()) ? overflow - ctx[i].size() : 0;
124 std::max(1_z, curr_col_start),
126 fmt::styled(
"^", colorize ? fmt::fg(fmt::color::red) : fmt::text_style()),
127 col_end - curr_col_start);
132 template <
typename T>
133 void helper(std::ostream& os,
const std::string& message,
const bool colorize,
const std::string& filename,
const std::string& code,
const T& expr,
134 const std::size_t line, std::size_t column,
const std::size_t sym_size)
137 fmt::print(os,
"In file {}\n", filename);
138 fmt::print(os,
"At {} @ {}:{}\n", expr, line + 1, column);
141 makeContext(os, code, line, column, sym_size, colorize);
144 for (
const auto& text : message_lines)
145 fmt::print(os,
" {}\n", text);
150 std::stringstream ss;
152 std::size_t size = 3;
154 size = node.
string().size();
172 if (
const char* nocolor = std::getenv(
"NOCOLOR"); nocolor !=
nullptr)
175 std::string escaped_symbol;
178 switch (e.
symbol.value().codepoint())
180 case '\n': escaped_symbol =
"'\\n'";
break;
181 case '\r': escaped_symbol =
"'\\r'";
break;
182 case '\t': escaped_symbol =
"'\\t'";
break;
183 case '\v': escaped_symbol =
"'\\v'";
break;
184 case '\0': escaped_symbol =
"EOF";
break;
185 case ' ': escaped_symbol =
"' '";
break;
187 escaped_symbol = e.
symbol.value().c_str();
191 escaped_symbol = e.
expr;
193 std::string file_content;
Lots of utilities about string, filesystem and more.
Constants used by ArkScript.
ArkScript homemade exceptions.
Lots of utilities about the filesystem.
User defined literals for Ark internals.
AST node used by the parser, optimizer and compiler.
A node of an Abstract Syntax Tree for ArkScript.
const std::string & filename() const noexcept
Return the filename in which this node was created.
const std::string & string() const noexcept
Return the string held by the value (if the node type allows it)
std::string repr() const noexcept
Compute a representation of the node without any comments or additional sugar, colors,...
std::size_t col() const noexcept
Get the column at which this node was created.
bool isStringLike() const noexcept
Check if the node is a string like node.
std::size_t line() const noexcept
Get the line at which this node was created.
bool isPairableChar(const char c)
ARK_API void makeContext(std::ostream &os, const std::string &code, std::size_t target_line, std::size_t col_start, std::size_t sym_size, bool colorize)
Helper to create a colorized context to report errors to the user.
void colorizeLine(const std::string &line, LineColorContextCounts &line_color_context_counts, std::ostream &ss)
void helper(std::ostream &os, const std::string &message, const bool colorize, const std::string &filename, const std::string &code, const T &expr, const std::size_t line, std::size_t column, const std::size_t sym_size)
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.
std::string readFile(const std::string &name)
Helper to read a file.
std::vector< std::string > splitString(const std::string &source, const char sep)
Cut a string into pieces, given a character separator.
CodeError thrown by the compiler (parser, macro processor, optimizer, and compiler itself)
const std::string filename
const std::optional< internal::utf8_char_t > symbol