2025-05-08 10:49:32 +01:00
|
|
|
#include <blue/term/print.h>
|
|
|
|
|
#include <ivy/diag.h>
|
|
|
|
|
#include <ivy/line-source.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#define NR_NAMES 6
|
|
|
|
|
|
|
|
|
|
#define ERROR_CLASS(id, title) \
|
|
|
|
|
[id] = {.c_type = IVY_DIAG_ERROR, .c_title = (title)}
|
|
|
|
|
|
|
|
|
|
#define MSG(id, content) [id] = {.msg_content = (content)}
|
|
|
|
|
|
|
|
|
|
enum {
|
|
|
|
|
E_NONE = 0,
|
|
|
|
|
E_UNRECOGNISED_SYMBOL,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum {
|
|
|
|
|
MSG_NONE,
|
|
|
|
|
MSG_SYMBOL_NOT_RECOGNISED,
|
|
|
|
|
MSG_CORRECTION_1,
|
|
|
|
|
MSG_EXAMPLE_2,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const char *fake_file_content[] = {
|
|
|
|
|
"var x = 32.\n",
|
|
|
|
|
"var y = 64.\n",
|
|
|
|
|
"var z = x $ y.\n",
|
|
|
|
|
};
|
|
|
|
|
static const size_t fake_file_lines
|
|
|
|
|
= sizeof fake_file_content / sizeof fake_file_content[0];
|
|
|
|
|
|
|
|
|
|
static enum ivy_status get_name(
|
|
|
|
|
struct ivy_line_source *src, char *buf, size_t count, size_t *nr_read)
|
|
|
|
|
{
|
|
|
|
|
*nr_read = snprintf(buf, count, "SAMPLE");
|
|
|
|
|
return IVY_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static enum ivy_status get_row(
|
|
|
|
|
struct ivy_line_source *src, size_t row, char *buf, size_t count,
|
|
|
|
|
size_t *nr_read)
|
|
|
|
|
{
|
|
|
|
|
if (row > fake_file_lines) {
|
|
|
|
|
return IVY_ERR_EOF;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *line = fake_file_content[row - 1];
|
|
|
|
|
size_t len = strlen(line);
|
|
|
|
|
if (len > count) {
|
|
|
|
|
len = count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memcpy(buf, line, len);
|
|
|
|
|
buf[len - 1] = 0;
|
|
|
|
|
*nr_read = len - 1;
|
|
|
|
|
|
|
|
|
|
return IVY_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct ivy_line_source source_file = {
|
|
|
|
|
.s_get_name = get_name,
|
|
|
|
|
.s_get_row = get_row,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const struct ivy_diag_class diag_classes[] = {
|
|
|
|
|
ERROR_CLASS(E_UNRECOGNISED_SYMBOL, "Unrecognised symbol"),
|
|
|
|
|
};
|
|
|
|
|
static const size_t nr_diag_classes = sizeof diag_classes / sizeof diag_classes[0];
|
|
|
|
|
|
|
|
|
|
static const struct ivy_diag_msg diag_msg[] = {
|
|
|
|
|
MSG(MSG_SYMBOL_NOT_RECOGNISED,
|
|
|
|
|
"encountered a symbol that is not part of the Ivy syntax."),
|
|
|
|
|
MSG(MSG_CORRECTION_1,
|
|
|
|
|
"perhaps you meant to use an arithmetic operator instead?"),
|
|
|
|
|
MSG(MSG_EXAMPLE_2, "an example diagnostic message."),
|
|
|
|
|
};
|
|
|
|
|
static const size_t nr_diag_msg = sizeof diag_msg / sizeof diag_msg[0];
|
|
|
|
|
|
|
|
|
|
int main(void)
|
|
|
|
|
{
|
|
|
|
|
struct ivy_diag_ctx *ctx;
|
|
|
|
|
if (ivy_diag_ctx_create(&ctx) != IVY_OK) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-08 20:30:21 +01:00
|
|
|
ivy_diag_ctx_set_line_source(ctx, &source_file);
|
2025-05-08 10:49:32 +01:00
|
|
|
ivy_diag_ctx_set_class_definitions(ctx, diag_classes, nr_diag_classes);
|
|
|
|
|
ivy_diag_ctx_set_msg_definitions(ctx, diag_msg, nr_diag_msg);
|
|
|
|
|
|
|
|
|
|
const struct ivy_diag_highlight hl[] = {
|
|
|
|
|
IVY_DIAG_HL(ERROR, 3, 11, 3, 11),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const struct ivy_diag_highlight hl2[] = {
|
|
|
|
|
IVY_DIAG_HL(HINT, 3, 11, 3, 11),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const struct ivy_diag_amendment amend[] = {
|
|
|
|
|
IVY_DIAG_REPLACE(3, 11, 1, "+"),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct ivy_diag *diag
|
|
|
|
|
= ivy_diag_ctx_create_diag(ctx, E_UNRECOGNISED_SYMBOL);
|
|
|
|
|
ivy_diag_set_location(diag, 3, 11);
|
|
|
|
|
ivy_diag_push_msg(diag, MSG_SYMBOL_NOT_RECOGNISED);
|
|
|
|
|
ivy_diag_push_snippet(
|
|
|
|
|
diag, 1, 3, amend, sizeof amend / sizeof amend[0], hl,
|
|
|
|
|
sizeof hl / sizeof hl[0]);
|
|
|
|
|
ivy_diag_push_msg(diag, MSG_CORRECTION_1);
|
|
|
|
|
ivy_diag_push_snippet(
|
|
|
|
|
diag, 1, 3, amend, sizeof amend / sizeof amend[0], hl2,
|
|
|
|
|
sizeof hl2 / sizeof hl2[0]);
|
|
|
|
|
ivy_diag_push_msg(diag, MSG_EXAMPLE_2);
|
|
|
|
|
|
|
|
|
|
struct ivy_diag_stream stream;
|
|
|
|
|
ivy_diag_stream_init_tty(&stream, b_stdtty);
|
|
|
|
|
ivy_diag_ctx_write(ctx, IVY_DIAG_FORMAT_PRETTY, &stream);
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
b_printf(
|
|
|
|
|
"[cyan]--- UNRECOGNISED SYMBOL "
|
|
|
|
|
"-------------------------"
|
|
|
|
|
"--------------------------[reset]\n");
|
|
|
|
|
b_printf(" [cyan]> src/std/io/StreamReader.im[reset]:8:11\n\n");
|
|
|
|
|
|
|
|
|
|
b_printf(
|
|
|
|
|
" encountered a symbol that is not part of the Ivy "
|
|
|
|
|
"syntax.\n\n");
|
|
|
|
|
|
|
|
|
|
b_printf(" [cyan]6 |[reset] var x = 32.\n");
|
|
|
|
|
b_printf(" [cyan]7 |[reset] var y = 64.\n");
|
|
|
|
|
b_printf(" [cyan]8 |[reset] var z = x [red]$[reset] y.\n");
|
|
|
|
|
b_printf(" [red]^[reset]\n\n");
|
|
|
|
|
|
|
|
|
|
b_printf("\n\n");
|
|
|
|
|
|
|
|
|
|
b_printf(
|
|
|
|
|
"[red,bold]error[[E0102][reset]: [bold]encountered an "
|
|
|
|
|
"unrecognised symbol[reset]\n");
|
|
|
|
|
b_printf(" [blue,bold]-->[reset] src/std/io/StreamReader.im\n");
|
|
|
|
|
b_printf(" [blue,bold] |[reset]\n");
|
|
|
|
|
b_printf(" [blue,bold]6 |[reset] var x = 32.\n");
|
|
|
|
|
b_printf(" [blue,bold]7 |[reset] var y = 64.\n");
|
|
|
|
|
b_printf(" [blue,bold]8 |[reset] var z = x [red,bold]$[reset] y.\n");
|
|
|
|
|
b_printf(" [blue,bold] |[reset] [red,bold]^[reset]\n");
|
|
|
|
|
|
|
|
|
|
b_printf("\n\n");
|
|
|
|
|
|
|
|
|
|
b_printf(" [red,bold]\u2A2F[reset] unrecognised symbol\n");
|
|
|
|
|
b_printf(" [cyan,bold]>[reset] src/std/io/StreamReader.im\n");
|
|
|
|
|
b_printf(" \u256D\u2500\u2500\u2500\n");
|
|
|
|
|
b_printf(" [dark_grey]0[reset] \u2502 var x = 2 $ 3.\n");
|
|
|
|
|
b_printf(" \u00B7 [green]\u252C[reset]\n");
|
|
|
|
|
b_printf(
|
|
|
|
|
" \u00B7 [green]\u2570\u2500\u2500 this symbol is "
|
|
|
|
|
"not "
|
|
|
|
|
"used in Ivy syntax.[reset]\n");
|
|
|
|
|
b_printf(" \u2570\u2500\u2500\u2500\n");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|