lang: lex: add diagnostic support

This commit is contained in:
2025-05-08 20:31:55 +01:00
parent cc99e7440e
commit a28874145c
3 changed files with 35 additions and 0 deletions

View File

@@ -136,12 +136,14 @@ struct ivy_token {
struct ivy_lexer_symbol_node;
struct ivy_lexer_state;
struct ivy_lexer;
struct ivy_diag_ctx;
IVY_API enum ivy_status ivy_lexer_create(struct ivy_lexer **lex);
IVY_API void ivy_lexer_destroy(struct ivy_lexer *lex);
IVY_API void ivy_lexer_set_source(
struct ivy_lexer *lex, struct ivy_line_source *src);
IVY_API void ivy_lexer_set_diag_ctx(struct ivy_lexer *lex, struct ivy_diag_ctx *ctx);
IVY_API enum ivy_status ivy_lexer_get_status(struct ivy_lexer *lex);
IVY_API struct ivy_token *ivy_lexer_peek(struct ivy_lexer *lex);

View File

@@ -6,6 +6,8 @@
#include <blue/object/number.h>
#include <blue/object/string.h>
#include <ctype.h>
#include <ivy/diag.h>
#include <ivy/lang/diag.h>
#include <ivy/lang/lex.h>
#include <stdbool.h>
#include <stdio.h>
@@ -338,6 +340,11 @@ void ivy_lexer_set_source(struct ivy_lexer *lex, struct ivy_line_source *src)
lex->lex_source = src;
}
void ivy_lexer_set_diag_ctx(struct ivy_lexer *lex, struct ivy_diag_ctx *ctx)
{
lex->lex_diag_ctx = ctx;
}
enum ivy_status ivy_lexer_get_status(struct ivy_lexer *lex)
{
return lex->lex_status;
@@ -728,6 +735,11 @@ static enum ivy_status read_atom(struct ivy_lexer *lex)
advance(lex);
}
if (b_string_get_size(str, B_STRLEN_NORMAL) == 0) {
/* TODO report empty atom error */
return IVY_ERR_BAD_SYNTAX;
}
char *s = b_string_steal(str);
return push_atom(lex, s);
}
@@ -998,6 +1010,25 @@ static enum ivy_status read_ident(struct ivy_lexer *lex)
return push_token(lex, tok);
}
static void report_unrecognised_char(struct ivy_lexer *lex, int c)
{
struct ivy_diag *diag = ivy_diag_ctx_create_diag(
lex->lex_diag_ctx, IVY_LANG_E_UNRECOGNISED_SYMBOL);
ivy_diag_set_location(diag, lex->lex_cursor_row, lex->lex_cursor_col);
ivy_diag_push_msg(diag, IVY_LANG_MSG_UNKNOWN_SYMBOL_ENCOUNTERED);
const struct ivy_diag_highlight hl[] = {
IVY_DIAG_HL(
ERROR, lex->lex_cursor_row, lex->lex_cursor_col,
lex->lex_cursor_row, lex->lex_cursor_col),
};
const size_t nr_hl = sizeof hl / sizeof hl[0];
ivy_diag_push_snippet(
diag, lex->lex_cursor_row, lex->lex_cursor_row, NULL, 0, hl, nr_hl);
}
static enum ivy_status pump_tokens(struct ivy_lexer *lex)
{
struct lexer_state *state = get_lexer_state(lex);
@@ -1059,6 +1090,7 @@ static enum ivy_status pump_tokens(struct ivy_lexer *lex)
return read_number(lex);
}
report_unrecognised_char(lex, c);
return IVY_ERR_BAD_SYNTAX;
}

View File

@@ -10,6 +10,7 @@
struct ivy_lexer {
struct ivy_lexer_symbol_node *lex_sym_tree;
struct ivy_diag_ctx *lex_diag_ctx;
struct ivy_line_source *lex_source;
b_dict *lex_keywords;
enum ivy_status lex_status;