lang: ast: add diag support to parser
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
|
||||||
#include <blue/core/queue.h>
|
#include <blue/core/queue.h>
|
||||||
|
#include <ivy/diag.h>
|
||||||
#include <ivy/lang/ast.h>
|
#include <ivy/lang/ast.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -67,6 +68,13 @@ void ivy_parser_destroy(struct ivy_parser *parser, struct ivy_ast_node **result)
|
|||||||
free(parser);
|
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)
|
enum ivy_status ivy_parser_get_status(struct ivy_parser *parser)
|
||||||
{
|
{
|
||||||
return parser->p_status;
|
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);
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
#define _AST_CTX_H_
|
#define _AST_CTX_H_
|
||||||
|
|
||||||
#include <blue/core/queue.h>
|
#include <blue/core/queue.h>
|
||||||
|
#include <ivy/diag.h>
|
||||||
#include <ivy/lang/ast.h>
|
#include <ivy/lang/ast.h>
|
||||||
|
#include <ivy/lang/diag.h>
|
||||||
#include <ivy/status.h>
|
#include <ivy/status.h>
|
||||||
|
|
||||||
#define parser_get_state(parser, state_type) \
|
#define parser_get_state(parser, state_type) \
|
||||||
@@ -19,6 +21,7 @@ struct parser_state {
|
|||||||
|
|
||||||
struct ivy_parser {
|
struct ivy_parser {
|
||||||
enum ivy_status p_status;
|
enum ivy_status p_status;
|
||||||
|
struct ivy_diag_ctx *p_diag_ctx;
|
||||||
b_queue p_state;
|
b_queue p_state;
|
||||||
b_queue p_token_queue;
|
b_queue p_token_queue;
|
||||||
b_queue p_node_queue;
|
b_queue p_node_queue;
|
||||||
@@ -40,4 +43,8 @@ extern void parser_replace_current_node(
|
|||||||
extern enum ivy_status parser_add_child(
|
extern enum ivy_status parser_add_child(
|
||||||
struct ivy_parser *parser, struct ivy_ast_node *new_node);
|
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
|
#endif
|
||||||
|
|||||||
@@ -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)
|
void ivy_ast_node_destroy(struct ivy_ast_node *node)
|
||||||
{
|
{
|
||||||
struct ivy_ast_node_iterator it = {};
|
struct ivy_ast_node_iterator it = {};
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <ivy/misc.h>
|
#include <ivy/misc.h>
|
||||||
#include <ivy/status.h>
|
#include <ivy/status.h>
|
||||||
|
|
||||||
|
struct ivy_diag_ctx;
|
||||||
struct ivy_token;
|
struct ivy_token;
|
||||||
struct ivy_parser;
|
struct ivy_parser;
|
||||||
struct b_string;
|
struct b_string;
|
||||||
@@ -72,6 +73,8 @@ struct ivy_ast_node_iterator_entry {
|
|||||||
|
|
||||||
struct ivy_ast_node {
|
struct ivy_ast_node {
|
||||||
enum ivy_ast_node_type n_type;
|
enum ivy_ast_node_type n_type;
|
||||||
|
struct ivy_ast_node *n_parent;
|
||||||
|
struct ivy_char_cell n_start, n_end;
|
||||||
b_queue_entry n_entry;
|
b_queue_entry n_entry;
|
||||||
struct ivy_ast_node_iterator_entry n_it;
|
struct ivy_ast_node_iterator_entry n_it;
|
||||||
};
|
};
|
||||||
@@ -332,6 +335,8 @@ IVY_API enum ivy_status ivy_parser_create(struct ivy_parser **parser);
|
|||||||
IVY_API void ivy_parser_destroy(
|
IVY_API void ivy_parser_destroy(
|
||||||
struct ivy_parser *parser, struct ivy_ast_node **result);
|
struct ivy_parser *parser, struct ivy_ast_node **result);
|
||||||
|
|
||||||
|
IVY_API enum ivy_status ivy_parser_set_diag_ctx(
|
||||||
|
struct ivy_parser *parser, struct ivy_diag_ctx *ctx);
|
||||||
IVY_API enum ivy_status ivy_parser_get_status(struct ivy_parser *parser);
|
IVY_API enum ivy_status ivy_parser_get_status(struct ivy_parser *parser);
|
||||||
IVY_API bool ivy_parser_is_node_complete(struct ivy_parser *parser);
|
IVY_API bool ivy_parser_is_node_complete(struct ivy_parser *parser);
|
||||||
IVY_API struct ivy_ast_node *ivy_parser_root_node(struct ivy_parser *parser);
|
IVY_API struct ivy_ast_node *ivy_parser_root_node(struct ivy_parser *parser);
|
||||||
@@ -345,6 +350,12 @@ IVY_API enum ivy_status ivy_ast_node_iterate(
|
|||||||
struct ivy_ast_node *node, struct ivy_ast_node_iterator *it,
|
struct ivy_ast_node *node, struct ivy_ast_node_iterator *it,
|
||||||
ivy_ast_node_iteration_callback callback, void *arg);
|
ivy_ast_node_iteration_callback callback, void *arg);
|
||||||
IVY_API void ivy_ast_node_to_string(struct ivy_ast_node *node, struct b_string *out);
|
IVY_API void ivy_ast_node_to_string(struct ivy_ast_node *node, struct b_string *out);
|
||||||
|
IVY_API void ivy_ast_node_set_bounds_from_token(
|
||||||
|
struct ivy_ast_node *parent, const struct ivy_token *tok);
|
||||||
|
IVY_API void ivy_ast_node_extend_bounds(
|
||||||
|
struct ivy_ast_node *parent, const struct ivy_ast_node *child);
|
||||||
|
IVY_API void ivy_ast_node_extend_bounds_recursive(
|
||||||
|
struct ivy_ast_node *parent, const struct ivy_ast_node *child);
|
||||||
IVY_API void ivy_ast_node_destroy(struct ivy_ast_node *node);
|
IVY_API void ivy_ast_node_destroy(struct ivy_ast_node *node);
|
||||||
|
|
||||||
IVY_API const char *ivy_ast_node_type_to_string(enum ivy_ast_node_type v);
|
IVY_API const char *ivy_ast_node_type_to_string(enum ivy_ast_node_type v);
|
||||||
|
|||||||
Reference in New Issue
Block a user