lang: ast: add diag support to parser

This commit is contained in:
2025-05-08 22:28:01 +01:00
parent a0f1931c00
commit c12371f0ec
4 changed files with 86 additions and 0 deletions

View File

@@ -4,6 +4,7 @@
#include "node.h"
#include <blue/core/queue.h>
#include <ivy/diag.h>
#include <ivy/lang/ast.h>
#include <stddef.h>
#include <stdio.h>
@@ -67,6 +68,13 @@ void ivy_parser_destroy(struct ivy_parser *parser, struct ivy_ast_node **result)
free(parser);
}
enum ivy_status ivy_parser_set_diag_ctx(
struct ivy_parser *parser, struct ivy_diag_ctx *ctx)
{
parser->p_diag_ctx = ctx;
return IVY_OK;
}
enum ivy_status ivy_parser_get_status(struct ivy_parser *parser)
{
return parser->p_status;
@@ -266,3 +274,30 @@ struct ivy_ast_node *ivy_parser_dequeue_node(struct ivy_parser *parser)
return b_unbox(struct ivy_ast_node, entry, n_entry);
}
struct ivy_diag *parser_push_diag(
struct ivy_parser *parser, unsigned long diag_class, unsigned long msg,
struct ivy_token *tok)
{
struct ivy_diag *diag
= ivy_diag_ctx_create_diag(parser->p_diag_ctx, diag_class);
if (msg != 0) {
ivy_diag_push_msg(diag, msg);
}
if (tok) {
const struct ivy_diag_highlight hl[] = {
IVY_DIAG_HL(
ERROR, tok->t_start.c_row, tok->t_start.c_col,
tok->t_end.c_row, tok->t_end.c_col),
};
const size_t nr_hl = sizeof hl / sizeof hl[0];
ivy_diag_push_snippet(
diag, tok->t_start.c_row, tok->t_end.c_row, NULL, 0, hl,
nr_hl);
};
return diag;
}

View File

@@ -2,7 +2,9 @@
#define _AST_CTX_H_
#include <blue/core/queue.h>
#include <ivy/diag.h>
#include <ivy/lang/ast.h>
#include <ivy/lang/diag.h>
#include <ivy/status.h>
#define parser_get_state(parser, state_type) \
@@ -19,6 +21,7 @@ struct parser_state {
struct ivy_parser {
enum ivy_status p_status;
struct ivy_diag_ctx *p_diag_ctx;
b_queue p_state;
b_queue p_token_queue;
b_queue p_node_queue;
@@ -40,4 +43,8 @@ extern void parser_replace_current_node(
extern enum ivy_status parser_add_child(
struct ivy_parser *parser, struct ivy_ast_node *new_node);
extern struct ivy_diag *parser_push_diag(
struct ivy_parser *parser, unsigned long diag_class, unsigned long msg,
struct ivy_token *tok);
#endif

View File

@@ -250,6 +250,39 @@ void ivy_ast_node_to_string(struct ivy_ast_node *node, struct b_string *out)
}
}
void ivy_ast_node_set_bounds_from_token(
struct ivy_ast_node *parent, const struct ivy_token *tok)
{
parent->n_start = tok->t_start;
parent->n_end = tok->t_end;
}
void ivy_ast_node_extend_bounds(
struct ivy_ast_node *parent, const struct ivy_ast_node *child)
{
if (child->n_start.c_row < parent->n_start.c_row) {
parent->n_start = child->n_start;
} else if (child->n_start.c_col < parent->n_start.c_col) {
parent->n_start.c_col = child->n_start.c_col;
}
if (child->n_end.c_row > parent->n_end.c_row) {
parent->n_end = child->n_end;
} else if (child->n_end.c_col > parent->n_end.c_col) {
parent->n_end.c_col = child->n_end.c_col;
}
}
void ivy_ast_node_extend_bounds_recursive(
struct ivy_ast_node *parent, const struct ivy_ast_node *child)
{
while (parent) {
ivy_ast_node_extend_bounds(parent, child);
child = parent;
parent = parent->n_parent;
}
}
void ivy_ast_node_destroy(struct ivy_ast_node *node)
{
struct ivy_ast_node_iterator it = {};