lang: lex: add diagnostic support
This commit is contained in:
@@ -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);
|
||||
|
||||
32
lang/lex.c
32
lang/lex.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user