mie: add a system for registering and producing detailed diagnostic messages
This commit is contained in:
43
mie/ctx.c
43
mie/ctx.c
@@ -4,6 +4,8 @@
|
||||
#include <blue/ds/string.h>
|
||||
#include <mie/attribute/attribute-definition.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/diag/class.h>
|
||||
#include <mie/diag/diag.h>
|
||||
#include <mie/dialect/arith.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
@@ -484,3 +486,44 @@ enum mie_status mie_ctx_get_pass(
|
||||
*out = pass;
|
||||
return status;
|
||||
}
|
||||
|
||||
struct mie_diag *mie_ctx_push_diag(
|
||||
struct mie_ctx *ctx, struct mie_line_source *src,
|
||||
const struct mie_file_cell *loc, const char *dialect_name,
|
||||
unsigned long diag_class)
|
||||
{
|
||||
struct mie_diag *diag = malloc(sizeof *diag);
|
||||
if (!diag) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct mie_dialect *dialect = mie_ctx_get_dialect(ctx, dialect_name);
|
||||
if (!dialect) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (diag_class >= dialect->d_nr_diag_classes) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(diag, 0x0, sizeof *diag);
|
||||
|
||||
diag->diag_src = src;
|
||||
diag->diag_loc = *loc;
|
||||
diag->diag_parent = dialect;
|
||||
diag->diag_class = &dialect->d_diag_classes[diag_class];
|
||||
|
||||
b_queue_push_back(&ctx->ctx_diag, &diag->diag_entry);
|
||||
|
||||
return diag;
|
||||
}
|
||||
|
||||
struct mie_diag *mie_ctx_pop_diag(struct mie_ctx *ctx)
|
||||
{
|
||||
b_queue_entry *entry = b_queue_pop_front(&ctx->ctx_diag);
|
||||
if (!entry) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return b_unbox(struct mie_diag, entry, diag_entry);
|
||||
}
|
||||
|
||||
106
mie/diag/diag.c
Normal file
106
mie/diag/diag.c
Normal file
@@ -0,0 +1,106 @@
|
||||
#include <blue/ds/string.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/diag/amendment.h>
|
||||
#include <mie/diag/component.h>
|
||||
#include <mie/diag/diag.h>
|
||||
#include <mie/diag/highlight.h>
|
||||
#include <mie/diag/msg.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct mie_diag_c_msg *diag_msg_create(const struct mie_diag_msg *content)
|
||||
{
|
||||
struct mie_diag_c_msg *out = malloc(sizeof *out);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(out, 0x0, sizeof *out);
|
||||
|
||||
out->msg_base.c_type = MIE_DIAG_COMPONENT_MSG;
|
||||
out->msg_content = b_strdup(content->msg_content);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
struct mie_diag_c_snippet *diag_snippet_create(
|
||||
unsigned long first_line, unsigned long last_line,
|
||||
const struct mie_diag_amendment *amendments, size_t nr_amendments,
|
||||
const struct mie_diag_highlight *highlights, size_t nr_highlights)
|
||||
{
|
||||
struct mie_diag_c_snippet *out = malloc(sizeof *out);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(out, 0x0, sizeof *out);
|
||||
|
||||
out->s_base.c_type = MIE_DIAG_COMPONENT_SNIPPET;
|
||||
out->s_first_line = first_line;
|
||||
out->s_last_line = last_line;
|
||||
|
||||
out->s_nr_amendments = nr_amendments;
|
||||
out->s_amendments = calloc(nr_amendments, sizeof *amendments);
|
||||
if (!out->s_amendments) {
|
||||
free(out);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(out->s_amendments, amendments, nr_amendments * sizeof *amendments);
|
||||
|
||||
out->s_nr_highlights = nr_highlights;
|
||||
out->s_highlights = calloc(nr_highlights, sizeof *highlights);
|
||||
if (!out->s_highlights) {
|
||||
free(out->s_amendments);
|
||||
free(out);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(out->s_highlights, highlights, nr_highlights * sizeof *highlights);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void mie_diag_set_location(
|
||||
struct mie_diag *diag, unsigned long row, unsigned long col)
|
||||
{
|
||||
diag->diag_loc.c_row = row;
|
||||
diag->diag_loc.c_row = col;
|
||||
}
|
||||
|
||||
void mie_diag_push_msg(
|
||||
struct mie_diag *diag, struct mie_ctx *ctx, const char *dialect_name,
|
||||
unsigned long msg, ...)
|
||||
{
|
||||
struct mie_dialect *dialect = mie_ctx_get_dialect(ctx, dialect_name);
|
||||
if (!dialect) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg >= dialect->d_nr_diag_msgs) {
|
||||
return;
|
||||
}
|
||||
|
||||
const struct mie_diag_msg *msg_info = &dialect->d_diag_msgs[msg];
|
||||
|
||||
struct mie_diag_c_msg *c_msg = diag_msg_create(msg_info);
|
||||
if (!c_msg) {
|
||||
return;
|
||||
}
|
||||
|
||||
b_queue_push_back(&diag->diag_components, &c_msg->msg_base.c_entry);
|
||||
}
|
||||
|
||||
void mie_diag_push_snippet(
|
||||
struct mie_diag *diag, unsigned long first_line, unsigned long last_line,
|
||||
const struct mie_diag_amendment *amendments, size_t nr_amendments,
|
||||
const struct mie_diag_highlight *highlights, size_t nr_highlights)
|
||||
{
|
||||
struct mie_diag_c_snippet *c_snippet = diag_snippet_create(
|
||||
first_line, last_line, amendments, nr_amendments, highlights,
|
||||
nr_highlights);
|
||||
if (!c_snippet) {
|
||||
return;
|
||||
}
|
||||
|
||||
b_queue_push_back(&diag->diag_components, &c_snippet->s_base.c_entry);
|
||||
}
|
||||
6
mie/diag/diag.h
Normal file
6
mie/diag/diag.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef _DIAG_DIAG_H_
|
||||
#define _DIAG_DIAG_H_
|
||||
|
||||
#include <blue/core/queue.h>
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,6 @@
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/diag/class.h>
|
||||
#include <mie/diag/msg.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/macros.h>
|
||||
@@ -81,9 +83,14 @@ struct mie_attribute *mie_ctx_get_index(struct mie_ctx *ctx, size_t val)
|
||||
dialect->ctx_indices, ctx, val);
|
||||
}
|
||||
|
||||
MIE_DIAG_CLASS_LIST_EXTERN(mie_builtin_diag);
|
||||
MIE_DIAG_MSG_LIST_EXTERN(mie_builtin_msg);
|
||||
|
||||
MIE_DIALECT_BEGIN(mie_builtin, struct builtin_dialect, "builtin")
|
||||
MIE_DIALECT_INIT(init);
|
||||
MIE_DIALECT_CLEANUP(cleanup);
|
||||
MIE_DIALECT_DIAG_CLASS_LIST(mie_builtin_diag);
|
||||
MIE_DIALECT_DIAG_MSG_LIST(mie_builtin_msg);
|
||||
MIE_DIALECT_ADD_TRAIT(mie_builtin_isolated_from_above);
|
||||
MIE_DIALECT_ADD_TRAIT(mie_builtin_symbol_table);
|
||||
MIE_DIALECT_ADD_TYPE(mie_builtin_int);
|
||||
|
||||
16
mie/dialect/builtin/diag.c
Normal file
16
mie/dialect/builtin/diag.c
Normal file
@@ -0,0 +1,16 @@
|
||||
#include <mie/diag/class.h>
|
||||
#include <mie/diag/msg.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/macros.h>
|
||||
|
||||
#define MIE_DIAG_CLASS_PREFIX MIE_BUILTIN_E
|
||||
#define MIE_DIAG_MSG_PREFIX MIE_BUILTIN_MSG
|
||||
|
||||
MIE_DIAG_CLASS_LIST_BEGIN(mie_builtin_diag)
|
||||
MIE_DIAG_CLASS(UNRECOGNISED_TOKEN, ERROR, "Unrecognised token")
|
||||
MIE_DIAG_CLASS(UNRESOLVED_VALUE, ERROR, "Unresolved value")
|
||||
MIE_DIAG_CLASS_LIST_END(mie_builtin_diag)
|
||||
|
||||
MIE_DIAG_MSG_LIST_BEGIN(mie_builtin_msg)
|
||||
MIE_DIAG_MSG(UNRECOGNISED_TOKEN, "encountered an unrecognised token.")
|
||||
MIE_DIAG_MSG_LIST_END(mie_builtin_msg)
|
||||
@@ -7,7 +7,10 @@
|
||||
|
||||
struct mie_op;
|
||||
struct mie_pass;
|
||||
struct mie_diag;
|
||||
struct mie_file_cell;
|
||||
struct mie_int_cache;
|
||||
struct mie_line_source;
|
||||
struct mie_index_cache;
|
||||
struct mie_string_cache;
|
||||
struct mie_attribute_map;
|
||||
@@ -31,6 +34,8 @@ struct mie_ctx {
|
||||
struct mie_id_map ctx_attributes;
|
||||
/* map of struct mie_pass_definition */
|
||||
struct mie_id_map ctx_passes;
|
||||
/* queue of struct mie_diag */
|
||||
b_queue ctx_diag;
|
||||
};
|
||||
|
||||
MIE_API struct mie_ctx *mie_ctx_create(void);
|
||||
@@ -73,4 +78,11 @@ MIE_API enum mie_status mie_ctx_get_pass(
|
||||
struct mie_ctx *ctx, const char *name,
|
||||
const struct mie_attribute_map *args, struct mie_pass **out);
|
||||
|
||||
MIE_API struct mie_diag *mie_ctx_push_diag(
|
||||
struct mie_ctx *ctx, struct mie_line_source *src,
|
||||
const struct mie_file_cell *loc, const char *dialect,
|
||||
unsigned long diag_class);
|
||||
|
||||
MIE_API struct mie_diag *mie_ctx_pop_diag(struct mie_ctx *ctx);
|
||||
|
||||
#endif
|
||||
|
||||
36
mie/include/mie/diag/amendment.h
Normal file
36
mie/include/mie/diag/amendment.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef MIE_DIAG_AMENDMENT_H_
|
||||
#define MIE_DIAG_AMENDMENT_H_
|
||||
|
||||
#include <mie/parse/file-span.h>
|
||||
|
||||
enum mie_diag_amendment_type {
|
||||
MIE_DIAG_AMENDMENT_NONE = 0,
|
||||
MIE_DIAG_AMENDMENT_ADD,
|
||||
MIE_DIAG_AMENDMENT_REMOVE,
|
||||
MIE_DIAG_AMENDMENT_REPLACE,
|
||||
};
|
||||
|
||||
struct mie_diag_amendment {
|
||||
enum mie_diag_amendment_type a_type;
|
||||
unsigned long __x;
|
||||
|
||||
union {
|
||||
struct {
|
||||
struct mie_file_cell a_loc;
|
||||
char *a_str;
|
||||
} a_add;
|
||||
|
||||
struct {
|
||||
struct mie_file_cell a_loc;
|
||||
unsigned long a_length;
|
||||
} a_remove;
|
||||
|
||||
struct {
|
||||
struct mie_file_cell a_loc;
|
||||
unsigned long a_length;
|
||||
char *a_str;
|
||||
} a_replace;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
18
mie/include/mie/diag/class.h
Normal file
18
mie/include/mie/diag/class.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef MIE_DIAG_CLASS_H_
|
||||
#define MIE_DIAG_CLASS_H_
|
||||
|
||||
enum mie_diag_class_type {
|
||||
MIE_DIAG_CLASS_NONE = 0,
|
||||
MIE_DIAG_CLASS_HINT,
|
||||
MIE_DIAG_CLASS_WARNING,
|
||||
MIE_DIAG_CLASS_ERROR,
|
||||
};
|
||||
|
||||
struct mie_diag_class {
|
||||
unsigned int c_id;
|
||||
const char *c_id_str_short, *c_id_str_long;
|
||||
enum mie_diag_class_type c_type;
|
||||
const char *c_title;
|
||||
};
|
||||
|
||||
#endif
|
||||
34
mie/include/mie/diag/component.h
Normal file
34
mie/include/mie/diag/component.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef MIE_DIAG_COMPONENT_H_
|
||||
#define MIE_DIAG_COMPONENT_H_
|
||||
|
||||
#include <blue/core/queue.h>
|
||||
#include <stddef.h>
|
||||
|
||||
enum mie_diag_component_type {
|
||||
MIE_DIAG_COMPONENT_NONE = 0,
|
||||
MIE_DIAG_COMPONENT_MSG,
|
||||
MIE_DIAG_COMPONENT_SNIPPET,
|
||||
};
|
||||
|
||||
struct mie_diag_component {
|
||||
enum mie_diag_component_type c_type;
|
||||
b_queue_entry c_entry;
|
||||
};
|
||||
|
||||
struct mie_diag_c_snippet {
|
||||
struct mie_diag_component s_base;
|
||||
unsigned long s_first_line, s_last_line;
|
||||
|
||||
struct mie_diag_amendment *s_amendments;
|
||||
size_t s_nr_amendments;
|
||||
|
||||
struct mie_diag_highlight *s_highlights;
|
||||
size_t s_nr_highlights;
|
||||
};
|
||||
|
||||
struct mie_diag_c_msg {
|
||||
struct mie_diag_component msg_base;
|
||||
char *msg_content;
|
||||
};
|
||||
|
||||
#endif
|
||||
39
mie/include/mie/diag/diag.h
Normal file
39
mie/include/mie/diag/diag.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef MIE_DIAG_DIAG_H_
|
||||
#define MIE_DIAG_DIAG_H_
|
||||
|
||||
#include <blue/core/queue.h>
|
||||
#include <mie/parse/file-span.h>
|
||||
|
||||
struct mie_ctx;
|
||||
struct mie_diag_class;
|
||||
struct mie_diag_amendment;
|
||||
struct mie_diag_highlight;
|
||||
|
||||
enum mie_diag_type {
|
||||
MIE_DIAG_NONE = 0,
|
||||
MIE_DIAG_HINT,
|
||||
MIE_DIAG_WARNING,
|
||||
MIE_DIAG_ERROR,
|
||||
};
|
||||
|
||||
struct mie_diag {
|
||||
struct mie_dialect *diag_parent;
|
||||
const struct mie_diag_class *diag_class;
|
||||
|
||||
struct mie_line_source *diag_src;
|
||||
struct mie_file_cell diag_loc;
|
||||
b_queue_entry diag_entry;
|
||||
b_queue diag_components;
|
||||
};
|
||||
|
||||
MIE_API void mie_diag_set_location(
|
||||
struct mie_diag *diag, unsigned long row, unsigned long col);
|
||||
MIE_API void mie_diag_push_msg(
|
||||
struct mie_diag *diag, struct mie_ctx *ctx, const char *dialect,
|
||||
unsigned long msg, ...);
|
||||
MIE_API void mie_diag_push_snippet(
|
||||
struct mie_diag *diag, unsigned long first_line, unsigned long last_line,
|
||||
const struct mie_diag_amendment *amendmends, size_t nr_amendments,
|
||||
const struct mie_diag_highlight *highlights, size_t nr_highlights);
|
||||
|
||||
#endif
|
||||
18
mie/include/mie/diag/highlight.h
Normal file
18
mie/include/mie/diag/highlight.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef MIE_DIAG_HIGHLIGHT_H_
|
||||
#define MIE_DIAG_HIGHLIGHT_H_
|
||||
|
||||
#include <mie/parse/file-span.h>
|
||||
|
||||
enum mie_diag_highlight_type {
|
||||
MIE_DIAG_HIGHLIGHT_NONE = 0,
|
||||
MIE_DIAG_HIGHLIGHT_HINT,
|
||||
MIE_DIAG_HIGHLIGHT_WARNING,
|
||||
MIE_DIAG_HIGHLIGHT_ERROR,
|
||||
};
|
||||
|
||||
struct mie_diag_highlight {
|
||||
enum mie_diag_highlight_type hl_type;
|
||||
struct mie_file_span hl_span;
|
||||
};
|
||||
|
||||
#endif
|
||||
10
mie/include/mie/diag/msg.h
Normal file
10
mie/include/mie/diag/msg.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef MIE_DIAG_MSG_H_
|
||||
#define MIE_DIAG_MSG_H_
|
||||
|
||||
struct mie_diag_msg {
|
||||
unsigned int msg_id;
|
||||
const char *msg_id_str_short, *msg_id_str_long;
|
||||
const char *msg_content;
|
||||
};
|
||||
|
||||
#endif
|
||||
0
mie/include/mie/diag/snippet.h
Normal file
0
mie/include/mie/diag/snippet.h
Normal file
@@ -15,6 +15,16 @@ struct mie_op;
|
||||
struct mie_int_type;
|
||||
struct mie_float_type;
|
||||
|
||||
enum mie_builtin_diag {
|
||||
MIE_BUILTIN_E_UNRECOGNISED_TOKEN,
|
||||
MIE_BUILTIN_E_UNRESOLVED_VALUE,
|
||||
};
|
||||
|
||||
enum mie_builtin_msg {
|
||||
MIE_BUILTIN_MSG_UNRECOGNISED_TOKEN,
|
||||
MIE_BUILTIN_MSG_UNRESOLVED_VALUE,
|
||||
};
|
||||
|
||||
enum mie_float_width {
|
||||
MIE_FLOAT_32 = 32,
|
||||
MIE_FLOAT_64 = 64,
|
||||
|
||||
@@ -13,6 +13,9 @@ struct mie_op_definition;
|
||||
struct mie_type_definition;
|
||||
struct mie_trait_definition;
|
||||
|
||||
struct mie_diag_class;
|
||||
struct mie_diag_msg;
|
||||
|
||||
struct mie_dialect {
|
||||
mie_id d_id;
|
||||
char *d_name;
|
||||
@@ -27,6 +30,12 @@ struct mie_dialect {
|
||||
struct mie_id_map d_attributes;
|
||||
/* map of struct mie_interface_definition */
|
||||
struct mie_id_map d_interfaces;
|
||||
/* array of mie_diag_class */
|
||||
struct mie_diag_class *d_diag_classes;
|
||||
size_t d_nr_diag_classes;
|
||||
/* array of mie_diag_msg */
|
||||
struct mie_diag_msg *d_diag_msgs;
|
||||
size_t d_nr_diag_msgs;
|
||||
|
||||
enum mie_status (*d_cleanup)(struct mie_dialect *);
|
||||
};
|
||||
|
||||
@@ -5,180 +5,186 @@
|
||||
/* DIALECT DEFINITION MACROS */
|
||||
/******************************************************************************/
|
||||
|
||||
#define MIE_DIALECT_BEGIN(func_prefix, c_struct, dialect_name) \
|
||||
struct mie_dialect *func_prefix##_dialect_create(struct mie_ctx *ctx) \
|
||||
{ \
|
||||
struct mie_dialect *self = mie_dialect_create( \
|
||||
ctx, dialect_name, sizeof(c_struct)); \
|
||||
if (!self) { \
|
||||
return NULL; \
|
||||
} \
|
||||
struct mie_op_definition *op = NULL; \
|
||||
struct mie_type_definition *type = NULL; \
|
||||
struct mie_trait_definition *trait = NULL; \
|
||||
struct mie_attribute_definition *attribute = NULL; \
|
||||
struct mie_interface_definition *interface = NULL;
|
||||
#define MIE_DIALECT_BEGIN(func_prefix, c_struct, dialect_name) \
|
||||
struct mie_dialect* func_prefix##_dialect_create(struct mie_ctx* ctx) \
|
||||
{ \
|
||||
struct mie_dialect* self = mie_dialect_create( \
|
||||
ctx, dialect_name, sizeof(c_struct)); \
|
||||
if (!self) { \
|
||||
return NULL; \
|
||||
} \
|
||||
struct mie_op_definition* op = NULL; \
|
||||
struct mie_type_definition* type = NULL; \
|
||||
struct mie_trait_definition* trait = NULL; \
|
||||
struct mie_attribute_definition* attribute = NULL; \
|
||||
struct mie_interface_definition* interface = NULL;
|
||||
|
||||
#define MIE_DIALECT_END() \
|
||||
return self; \
|
||||
}
|
||||
#define MIE_DIALECT_END() \
|
||||
return self; \
|
||||
}
|
||||
|
||||
#define MIE_DIALECT_INIT(func) func(self)
|
||||
#define MIE_DIALECT_INIT(func) func(self)
|
||||
#define MIE_DIALECT_CLEANUP(func) self->d_cleanup = (func)
|
||||
#define MIE_DIALECT_ADD_OP(op_id) \
|
||||
extern struct mie_op_definition *op_id##_op_create( \
|
||||
struct mie_dialect *, struct mie_ctx *); \
|
||||
op = op_id##_op_create(self, ctx)
|
||||
#define MIE_DIALECT_ADD_TYPE(type_id) \
|
||||
extern struct mie_type_definition *type_id##_type_create( \
|
||||
struct mie_dialect *, struct mie_ctx *); \
|
||||
type = type_id##_type_create(self, ctx)
|
||||
#define MIE_DIALECT_ADD_TRAIT(trait_id) \
|
||||
extern struct mie_trait_definition *trait_id##_trait_create( \
|
||||
struct mie_dialect *, struct mie_ctx *); \
|
||||
trait = trait_id##_trait_create(self, ctx)
|
||||
#define MIE_DIALECT_ADD_ATTRIBUTE(attr_id) \
|
||||
extern struct mie_attribute_definition *attr_id##_attribute_create( \
|
||||
struct mie_dialect *, struct mie_ctx *); \
|
||||
attribute = attr_id##_attribute_create(self, ctx)
|
||||
#define MIE_DIALECT_ADD_INTERFACE(iface_id) \
|
||||
extern struct mie_interface_definition *iface_id##_interface_create( \
|
||||
struct mie_dialect *, struct mie_ctx *); \
|
||||
interface = iface_id##_interface_create(self, ctx)
|
||||
#define MIE_DIALECT_DIAG_CLASS_LIST(list) \
|
||||
self->d_diag_classes = (list); \
|
||||
self->d_nr_diag_classes = (list##_count)
|
||||
#define MIE_DIALECT_DIAG_MSG_LIST(list) \
|
||||
self->d_diag_msgs = (list); \
|
||||
self->d_nr_diag_msgs = (list##_count)
|
||||
#define MIE_DIALECT_ADD_OP(op_id) \
|
||||
extern struct mie_op_definition* op_id##_op_create( \
|
||||
struct mie_dialect*, struct mie_ctx*); \
|
||||
op = op_id##_op_create(self, ctx)
|
||||
#define MIE_DIALECT_ADD_TYPE(type_id) \
|
||||
extern struct mie_type_definition* type_id##_type_create( \
|
||||
struct mie_dialect*, struct mie_ctx*); \
|
||||
type = type_id##_type_create(self, ctx)
|
||||
#define MIE_DIALECT_ADD_TRAIT(trait_id) \
|
||||
extern struct mie_trait_definition* trait_id##_trait_create( \
|
||||
struct mie_dialect*, struct mie_ctx*); \
|
||||
trait = trait_id##_trait_create(self, ctx)
|
||||
#define MIE_DIALECT_ADD_ATTRIBUTE(attr_id) \
|
||||
extern struct mie_attribute_definition* attr_id##_attribute_create( \
|
||||
struct mie_dialect*, struct mie_ctx*); \
|
||||
attribute = attr_id##_attribute_create(self, ctx)
|
||||
#define MIE_DIALECT_ADD_INTERFACE(iface_id) \
|
||||
extern struct mie_interface_definition* iface_id##_interface_create( \
|
||||
struct mie_dialect*, struct mie_ctx*); \
|
||||
interface = iface_id##_interface_create(self, ctx)
|
||||
|
||||
/******************************************************************************/
|
||||
/* OP DEFINITION MACROS */
|
||||
/******************************************************************************/
|
||||
|
||||
#define MIE_OP_DEFINITION_BEGIN(func_prefix, op_name) \
|
||||
struct mie_op_definition *func_prefix##_op_create( \
|
||||
struct mie_dialect *d, struct mie_ctx *ctx) \
|
||||
{ \
|
||||
struct mie_op_definition *op \
|
||||
= mie_op_definition_create(d, op_name); \
|
||||
if (!op) { \
|
||||
return NULL; \
|
||||
} \
|
||||
const struct mie_trait *trait = NULL; \
|
||||
struct mie_interface *i = NULL; \
|
||||
const struct mie_interface_definition *id = NULL;
|
||||
#define MIE_OP_DEFINITION_BEGIN(func_prefix, op_name) \
|
||||
struct mie_op_definition* func_prefix##_op_create( \
|
||||
struct mie_dialect* d, struct mie_ctx* ctx) \
|
||||
{ \
|
||||
struct mie_op_definition* op \
|
||||
= mie_op_definition_create(d, op_name); \
|
||||
if (!op) { \
|
||||
return NULL; \
|
||||
} \
|
||||
const struct mie_trait* trait = NULL; \
|
||||
struct mie_interface* i = NULL; \
|
||||
const struct mie_interface_definition* id = NULL;
|
||||
|
||||
#define MIE_OP_DEFINITION_END() \
|
||||
return op; \
|
||||
}
|
||||
#define MIE_OP_DEFINITION_END() \
|
||||
return op; \
|
||||
}
|
||||
|
||||
#define MIE_OP_DEFINITION_PRINT(func) op->op_print = (func)
|
||||
#define MIE_OP_DEFINITION_PARSE(func) op->op_parse = (func)
|
||||
#define MIE_OP_DEFINITION_TRAIT(trait_dialect, trait_name) \
|
||||
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
|
||||
mie_op_definition_add_trait(op, trait);
|
||||
#define MIE_OP_INTERFACE_BEGIN(dialect_name, if_name, c_struct) \
|
||||
id = mie_ctx_get_interface_definition(ctx, dialect_name, if_name); \
|
||||
if (id) { \
|
||||
c_struct *iface = (c_struct *)mie_interface_create(id);
|
||||
#define MIE_OP_DEFINITION_TRAIT(trait_dialect, trait_name) \
|
||||
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
|
||||
mie_op_definition_add_trait(op, trait);
|
||||
#define MIE_OP_INTERFACE_BEGIN(dialect_name, if_name, c_struct) \
|
||||
id = mie_ctx_get_interface_definition(ctx, dialect_name, if_name); \
|
||||
if (id) { \
|
||||
c_struct* iface = (c_struct*)mie_interface_create(id);
|
||||
#define MIE_OP_INTERFACE_FUNC(func_name) iface->func_name
|
||||
#define MIE_OP_INTERFACE_END() \
|
||||
mie_op_definition_add_interface(op, (struct mie_interface *)iface); \
|
||||
}
|
||||
#define MIE_OP_INTERFACE_END() \
|
||||
mie_op_definition_add_interface(op, (struct mie_interface*)iface); \
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* TYPE DEFINITION MACROS */
|
||||
/******************************************************************************/
|
||||
|
||||
#define MIE_TYPE_DEFINITION_BEGIN(func_prefix, type_name) \
|
||||
struct mie_type_definition *func_prefix##_type_create( \
|
||||
struct mie_dialect *d, struct mie_ctx *ctx) \
|
||||
{ \
|
||||
struct mie_type_definition *type \
|
||||
= mie_type_definition_create(d, type_name); \
|
||||
if (!type) { \
|
||||
return NULL; \
|
||||
} \
|
||||
const struct mie_trait *trait = NULL;
|
||||
#define MIE_TYPE_DEFINITION_BEGIN(func_prefix, type_name) \
|
||||
struct mie_type_definition* func_prefix##_type_create( \
|
||||
struct mie_dialect* d, struct mie_ctx* ctx) \
|
||||
{ \
|
||||
struct mie_type_definition* type \
|
||||
= mie_type_definition_create(d, type_name); \
|
||||
if (!type) { \
|
||||
return NULL; \
|
||||
} \
|
||||
const struct mie_trait* trait = NULL;
|
||||
|
||||
#define MIE_TYPE_DEFINITION_END() \
|
||||
return type; \
|
||||
}
|
||||
#define MIE_TYPE_DEFINITION_END() \
|
||||
return type; \
|
||||
}
|
||||
|
||||
#define MIE_TYPE_DEFINITION_FLAGS(flags) type->ty_flags = flags
|
||||
#define MIE_TYPE_DEFINITION_STRUCT(name) type->ty_data_size = sizeof(name)
|
||||
#define MIE_TYPE_DEFINITION_INIT(func) type->ty_init = (func)
|
||||
#define MIE_TYPE_DEFINITION_PRINT(func) type->ty_print = (func)
|
||||
#define MIE_TYPE_DEFINITION_PARSE(func) type->ty_parse = (func)
|
||||
#define MIE_TYPE_DEFINITION_FLAGS(flags) type->ty_flags = flags
|
||||
#define MIE_TYPE_DEFINITION_STRUCT(name) type->ty_data_size = sizeof(name)
|
||||
#define MIE_TYPE_DEFINITION_INIT(func) type->ty_init = (func)
|
||||
#define MIE_TYPE_DEFINITION_PRINT(func) type->ty_print = (func)
|
||||
#define MIE_TYPE_DEFINITION_PARSE(func) type->ty_parse = (func)
|
||||
#define MIE_TYPE_DEFINITION_BUILD_ID(func) type->ty_build_id = (func)
|
||||
#define MIE_TYPE_DEFINITION_INIT(func) type->ty_init = (func)
|
||||
#define MIE_TYPE_DEFINITION_CLEANUP(func) type->ty_cleanup = (func)
|
||||
#define MIE_TYPE_DEFINITION_TRAIT(trait_dialect, trait_name) \
|
||||
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
|
||||
mie_type_definition_add_trait(type, trait);
|
||||
#define MIE_TYPE_DEFINITION_INIT(func) type->ty_init = (func)
|
||||
#define MIE_TYPE_DEFINITION_CLEANUP(func) type->ty_cleanup = (func)
|
||||
#define MIE_TYPE_DEFINITION_TRAIT(trait_dialect, trait_name) \
|
||||
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
|
||||
mie_type_definition_add_trait(type, trait);
|
||||
|
||||
/******************************************************************************/
|
||||
/* TRAIT DEFINITION MACROS */
|
||||
/******************************************************************************/
|
||||
|
||||
#define MIE_TRAIT_DEFINITION_BEGIN(func_prefix, trait_name) \
|
||||
struct mie_trait_definition *func_prefix##_trait_create( \
|
||||
struct mie_dialect *d, struct mie_ctx *ctx) \
|
||||
{ \
|
||||
struct mie_trait_definition *trait \
|
||||
= mie_trait_definition_create(d, trait_name); \
|
||||
if (!trait) { \
|
||||
return NULL; \
|
||||
}
|
||||
#define MIE_TRAIT_DEFINITION_BEGIN(func_prefix, trait_name) \
|
||||
struct mie_trait_definition* func_prefix##_trait_create( \
|
||||
struct mie_dialect* d, struct mie_ctx* ctx) \
|
||||
{ \
|
||||
struct mie_trait_definition* trait \
|
||||
= mie_trait_definition_create(d, trait_name); \
|
||||
if (!trait) { \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#define MIE_TRAIT_DEFINITION_END() \
|
||||
return trait; \
|
||||
}
|
||||
#define MIE_TRAIT_DEFINITION_END() \
|
||||
return trait; \
|
||||
}
|
||||
|
||||
#define MIE_TRAIT_DEFINITION_TARGETS(targets) trait->tr_target = (targets)
|
||||
#define MIE_TRAIT_DEFINITION_STRUCT(name) trait->tr_data_size = sizeof(name)
|
||||
#define MIE_TRAIT_DEFINITION_PRINT(func) trait->tr_print = (func)
|
||||
#define MIE_TRAIT_DEFINITION_BUILD_ID(func) trait->tr_build_id = (func)
|
||||
#define MIE_TRAIT_DEFINITION_CLEANUP(func) trait->tr_cleanup = (func)
|
||||
#define MIE_TRAIT_DEFINITION_VALIDATE(func) trait->tr_validate = (func)
|
||||
#define MIE_TRAIT_DEFINITION_STRUCT(name) trait->tr_data_size = sizeof(name)
|
||||
#define MIE_TRAIT_DEFINITION_PRINT(func) trait->tr_print = (func)
|
||||
#define MIE_TRAIT_DEFINITION_BUILD_ID(func) trait->tr_build_id = (func)
|
||||
#define MIE_TRAIT_DEFINITION_CLEANUP(func) trait->tr_cleanup = (func)
|
||||
#define MIE_TRAIT_DEFINITION_VALIDATE(func) trait->tr_validate = (func)
|
||||
|
||||
/******************************************************************************/
|
||||
/* ATTRIBUTE DEFINITION MACROS */
|
||||
/******************************************************************************/
|
||||
|
||||
#define MIE_ATTRIBUTE_DEFINITION_BEGIN(func_prefix, attribute_name) \
|
||||
struct mie_attribute_definition *func_prefix##_attribute_create( \
|
||||
struct mie_dialect *d, struct mie_ctx *ctx) \
|
||||
{ \
|
||||
struct mie_attribute_definition *attribute \
|
||||
= mie_attribute_definition_create(d, attribute_name); \
|
||||
if (!attribute) { \
|
||||
return NULL; \
|
||||
}
|
||||
#define MIE_ATTRIBUTE_DEFINITION_BEGIN(func_prefix, attribute_name) \
|
||||
struct mie_attribute_definition* func_prefix##_attribute_create( \
|
||||
struct mie_dialect* d, struct mie_ctx* ctx) \
|
||||
{ \
|
||||
struct mie_attribute_definition* attribute \
|
||||
= mie_attribute_definition_create(d, attribute_name); \
|
||||
if (!attribute) { \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#define MIE_ATTRIBUTE_DEFINITION_END() \
|
||||
return attribute; \
|
||||
}
|
||||
#define MIE_ATTRIBUTE_DEFINITION_END() \
|
||||
return attribute; \
|
||||
}
|
||||
|
||||
#define MIE_ATTRIBUTE_DEFINITION_STRUCT(name) \
|
||||
attribute->a_data_size = sizeof(name)
|
||||
#define MIE_ATTRIBUTE_DEFINITION_INIT(func) attribute->a_init = (func)
|
||||
#define MIE_ATTRIBUTE_DEFINITION_STRUCT(name) \
|
||||
attribute->a_data_size = sizeof(name)
|
||||
#define MIE_ATTRIBUTE_DEFINITION_INIT(func) attribute->a_init = (func)
|
||||
#define MIE_ATTRIBUTE_DEFINITION_CLEANUP(func) attribute->a_cleanup = (func)
|
||||
#define MIE_ATTRIBUTE_DEFINITION_PRINT(func) attribute->a_print = (func)
|
||||
#define MIE_ATTRIBUTE_DEFINITION_PARSE(func) attribute->a_parse = (func)
|
||||
#define MIE_ATTRIBUTE_DEFINITION_PRINT(func) attribute->a_print = (func)
|
||||
#define MIE_ATTRIBUTE_DEFINITION_PARSE(func) attribute->a_parse = (func)
|
||||
|
||||
/******************************************************************************/
|
||||
/* INTERFACE DEFINITION MACROS */
|
||||
/******************************************************************************/
|
||||
|
||||
#define MIE_INTERFACE_DEFINITION_BEGIN(func_prefix, iface_name) \
|
||||
struct mie_interface_definition *func_prefix##_interface_create( \
|
||||
struct mie_dialect *d, struct mie_ctx *ctx) \
|
||||
{ \
|
||||
struct mie_interface_definition *i \
|
||||
= mie_interface_definition_create(d, iface_name); \
|
||||
if (!i) { \
|
||||
return NULL; \
|
||||
}
|
||||
#define MIE_INTERFACE_DEFINITION_BEGIN(func_prefix, iface_name) \
|
||||
struct mie_interface_definition* func_prefix##_interface_create( \
|
||||
struct mie_dialect* d, struct mie_ctx* ctx) \
|
||||
{ \
|
||||
struct mie_interface_definition* i \
|
||||
= mie_interface_definition_create(d, iface_name); \
|
||||
if (!i) { \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#define MIE_INTERFACE_DEFINITION_END() \
|
||||
return i; \
|
||||
}
|
||||
#define MIE_INTERFACE_DEFINITION_END() \
|
||||
return i; \
|
||||
}
|
||||
|
||||
#define MIE_INTERFACE_DEFINITION_STRUCT(name) i->if_size = sizeof(name)
|
||||
|
||||
@@ -186,84 +192,143 @@
|
||||
/* PASS DEFINITION MACROS */
|
||||
/******************************************************************************/
|
||||
|
||||
#define MIE_PASS_DEFINITION_BEGIN(prefix) \
|
||||
struct mie_pass_definition *prefix##_pass_create(struct mie_ctx *ctx) \
|
||||
{ \
|
||||
struct mie_pass_definition *p = mie_pass_definition_create(); \
|
||||
if (!p) { \
|
||||
return NULL; \
|
||||
}
|
||||
#define MIE_PASS_DEFINITION_BEGIN(prefix) \
|
||||
struct mie_pass_definition* prefix##_pass_create(struct mie_ctx* ctx) \
|
||||
{ \
|
||||
struct mie_pass_definition* p = mie_pass_definition_create(); \
|
||||
if (!p) { \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#define MIE_PASS_DEFINITION_END() \
|
||||
if (mie_ctx_register_pass(ctx, p) != MIE_SUCCESS) { \
|
||||
return NULL; \
|
||||
} \
|
||||
return p; \
|
||||
}
|
||||
#define MIE_PASS_DEFINITION_END() \
|
||||
if (mie_ctx_register_pass(ctx, p) != MIE_SUCCESS) { \
|
||||
return NULL; \
|
||||
} \
|
||||
return p; \
|
||||
}
|
||||
|
||||
#define MIE_PASS_NAME(name) p->p_name = (name)
|
||||
#define MIE_PASS_NAME(name) p->p_name = (name)
|
||||
#define MIE_PASS_DESCRIPTION(desc) p->p_description = (desc)
|
||||
#define MIE_PASS_STRUCT(c_struct) p->p_data_size = sizeof(c_struct)
|
||||
#define MIE_PASS_TYPE(type) p->p_type = (type)
|
||||
#define MIE_PASS_INIT(func) p->p_init = (func)
|
||||
#define MIE_PASS_TRANSFORM(func) \
|
||||
p->p_transform = (func); \
|
||||
p->p_type = MIE_PASS_TRANSFORM
|
||||
#define MIE_PASS_ANALYSE(func) \
|
||||
p->p_analyse = (func); \
|
||||
p->p_type = MIE_PASS_ANALYSE
|
||||
#define MIE_PASS_FILTER_OP(dialect, op) \
|
||||
p->p_filter.f_op = mie_ctx_get_op_definition(ctx, dialect, op)
|
||||
#define MIE_PASS_FILTER_TRAIT(dialect, tr) \
|
||||
p->p_filter.f_trait = mie_ctx_get_trait_definition(ctx, dialect, tr)
|
||||
#define MIE_PASS_FILTER_INTERFACE(dialect, ifn) \
|
||||
p->p_filter.f_iface = mie_ctx_get_iface_definition(ctx, dialect, ifn)
|
||||
#define MIE_PASS_STRUCT(c_struct) p->p_data_size = sizeof(c_struct)
|
||||
#define MIE_PASS_TYPE(type) p->p_type = (type)
|
||||
#define MIE_PASS_INIT(func) p->p_init = (func)
|
||||
#define MIE_PASS_TRANSFORM(func) \
|
||||
p->p_transform = (func); \
|
||||
p->p_type = MIE_PASS_TRANSFORM
|
||||
#define MIE_PASS_ANALYSE(func) \
|
||||
p->p_analyse = (func); \
|
||||
p->p_type = MIE_PASS_ANALYSE
|
||||
#define MIE_PASS_FILTER_OP(dialect, op) \
|
||||
p->p_filter.f_op = mie_ctx_get_op_definition(ctx, dialect, op)
|
||||
#define MIE_PASS_FILTER_TRAIT(dialect, tr) \
|
||||
p->p_filter.f_trait = mie_ctx_get_trait_definition(ctx, dialect, tr)
|
||||
#define MIE_PASS_FILTER_INTERFACE(dialect, ifn) \
|
||||
p->p_filter.f_iface = mie_ctx_get_iface_definition(ctx, dialect, ifn)
|
||||
|
||||
/******************************************************************************/
|
||||
/* PASS GROUP MACROS */
|
||||
/******************************************************************************/
|
||||
|
||||
#define MIE_PASS_GROUP_BEGIN(prefix) \
|
||||
enum mie_status prefix##_passes_register(struct mie_ctx *ctx) \
|
||||
{ \
|
||||
struct mie_pass_definition *pass = NULL;
|
||||
#define MIE_PASS_GROUP_BEGIN(prefix) \
|
||||
enum mie_status prefix##_passes_register(struct mie_ctx* ctx) \
|
||||
{ \
|
||||
struct mie_pass_definition* pass = NULL;
|
||||
|
||||
#define MIE_PASS_GROUP_END() \
|
||||
return MIE_SUCCESS; \
|
||||
}
|
||||
#define MIE_PASS_GROUP_END() \
|
||||
return MIE_SUCCESS; \
|
||||
}
|
||||
|
||||
#define MIE_PASS_GROUP_DECLARATION(prefix) \
|
||||
enum mie_status prefix##_passes_register(struct mie_ctx *);
|
||||
#define MIE_PASS_GROUP_DECLARATION(prefix) \
|
||||
enum mie_status prefix##_passes_register(struct mie_ctx*);
|
||||
|
||||
#define MIE_PASS_GROUP_ADD_PASS(id) \
|
||||
do { \
|
||||
extern struct mie_pass_definition *id##_pass_create( \
|
||||
struct mie_ctx *); \
|
||||
pass = id##_pass_create(ctx); \
|
||||
if (!pass) { \
|
||||
return MIE_ERR_INTERNAL_FAILURE; \
|
||||
} \
|
||||
} while (0)
|
||||
#define MIE_PASS_GROUP_ADD_PASS(id) \
|
||||
do { \
|
||||
extern struct mie_pass_definition* id##_pass_create( \
|
||||
struct mie_ctx*); \
|
||||
pass = id##_pass_create(ctx); \
|
||||
if (!pass) { \
|
||||
return MIE_ERR_INTERNAL_FAILURE; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/* REWRITE PATTER MACROS */
|
||||
/* REWRITE PATTERN MACROS */
|
||||
/******************************************************************************/
|
||||
|
||||
#define MIE_REWRITE_PATTERN_BEGIN(name) \
|
||||
struct mie_pattern *name##_create(struct mie_pattern_set *set) \
|
||||
{ \
|
||||
struct mie_pattern *self = mie_pattern_set_add(set); \
|
||||
if (!self) { \
|
||||
return NULL; \
|
||||
}
|
||||
#define MIE_REWRITE_PATTERN_END() \
|
||||
return self; \
|
||||
}
|
||||
#define MIE_REWRITE_PATTERN_BEGIN(name) \
|
||||
struct mie_pattern* name##_create(struct mie_pattern_set* set) \
|
||||
{ \
|
||||
struct mie_pattern* self = mie_pattern_set_add(set); \
|
||||
if (!self) { \
|
||||
return NULL; \
|
||||
}
|
||||
#define MIE_REWRITE_PATTERN_END() \
|
||||
return self; \
|
||||
}
|
||||
|
||||
#define MIE_REWRITE_PATTERN_ROOT(dialect_name, op_name) \
|
||||
self->p_root.t_dialect_name = (dialect_name); \
|
||||
self->p_root.t_op_name = (op_name)
|
||||
#define MIE_REWRITE_PATTERN_MATCH(func) self->p_match = (func)
|
||||
#define MIE_REWRITE_PATTERN_ROOT(dialect_name, op_name) \
|
||||
self->p_root.t_dialect_name = (dialect_name); \
|
||||
self->p_root.t_op_name = (op_name)
|
||||
#define MIE_REWRITE_PATTERN_MATCH(func) self->p_match = (func)
|
||||
#define MIE_REWRITE_PATTERN_REWRITE(func) self->p_rewrite = (func)
|
||||
|
||||
/******************************************************************************/
|
||||
/* DIAG CLASS MACROS */
|
||||
/******************************************************************************/
|
||||
|
||||
#define __MIE_CNAME2(x, y) x##_##y
|
||||
#define __MIE_CNAME1(x, y) __MIE_CNAME2(x, y)
|
||||
#define __MIE_CNAME(fun) __MIE_CNAME1(MIE_DIAG_CLASS_PREFIX, fun)
|
||||
|
||||
#define __MIE_CSNAME2(x, y) #x #y
|
||||
#define __MIE_CSNAME1(x, y) __MIE_CSNAME2(x, y)
|
||||
#define __MIE_CSNAME(fun) __MIE_CSNAME1(MIE_DIAG_CLASS_PREFIX, fun)
|
||||
|
||||
#define MIE_DIAG_CLASS_LIST_EXTERN(list_name) \
|
||||
extern struct mie_diag_class list_name[]; \
|
||||
extern const size_t list_name##_count
|
||||
#define MIE_DIAG_CLASS_LIST_BEGIN(list_name) \
|
||||
struct mie_diag_class list_name[] = {
|
||||
#define MIE_DIAG_CLASS_LIST_END(list_name) \
|
||||
} \
|
||||
; \
|
||||
const size_t list_name##_count = sizeof(list_name) / sizeof(list_name[0]);
|
||||
#define MIE_DIAG_CLASS(id, type, title) \
|
||||
[__MIE_CNAME(id)] = { \
|
||||
.c_id = __MIE_CNAME(id), \
|
||||
.c_type = MIE_DIAG_CLASS_##type, \
|
||||
.c_title = (title), \
|
||||
.c_id_str_short = #id, \
|
||||
.c_id_str_long = __MIE_CSNAME(id), \
|
||||
},
|
||||
|
||||
/******************************************************************************/
|
||||
/* DIAG MSG MACROS */
|
||||
/******************************************************************************/
|
||||
|
||||
#define __MIE_MNAME2(x, y) x##_##y
|
||||
#define __MIE_MNAME1(x, y) __MIE_CNAME2(x, y)
|
||||
#define __MIE_MNAME(fun) __MIE_CNAME1(MIE_DIAG_MSG_PREFIX, fun)
|
||||
|
||||
#define __MIE_MSNAME2(x, y) #x #y
|
||||
#define __MIE_MSNAME1(x, y) __MIE_CSNAME2(x, y)
|
||||
#define __MIE_MSNAME(fun) __MIE_CSNAME1(MIE_DIAG_MSG_PREFIX, fun)
|
||||
|
||||
#define MIE_DIAG_MSG_LIST_EXTERN(list_name) \
|
||||
extern struct mie_diag_msg list_name[]; \
|
||||
extern const size_t list_name##_count
|
||||
#define MIE_DIAG_MSG_LIST_BEGIN(list_name) \
|
||||
struct mie_diag_msg list_name[] = {
|
||||
#define MIE_DIAG_MSG_LIST_END(list_name) \
|
||||
} \
|
||||
; \
|
||||
const size_t list_name##_count = sizeof(list_name) / sizeof(list_name[0]);
|
||||
#define MIE_DIAG_MSG(id, content) \
|
||||
[__MIE_MNAME(id)] = { \
|
||||
.msg_id = __MIE_MNAME(id), \
|
||||
.msg_content = (content), \
|
||||
.msg_id_str_short = #id, \
|
||||
.msg_id_str_long = __MIE_MSNAME(id), \
|
||||
},
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
#ifndef MIE_PARSE_LEX_H_
|
||||
#define MIE_PARSE_LEX_H_
|
||||
|
||||
#include <blue/core/queue.h>
|
||||
#include <blue/core/stream.h>
|
||||
#include <mie/misc.h>
|
||||
#include <mie/status.h>
|
||||
|
||||
struct mie_lex;
|
||||
struct mie_ctx;
|
||||
struct mie_token;
|
||||
struct mie_line_source;
|
||||
|
||||
MIE_API struct mie_lex *mie_lex_create(struct mie_line_source *src);
|
||||
MIE_API struct mie_lex *mie_lex_create(
|
||||
struct mie_line_source *src, struct mie_ctx *ctx);
|
||||
MIE_API void mie_lex_destroy(struct mie_lex *lex);
|
||||
|
||||
MIE_API enum mie_status mie_lex_get_status(const struct mie_lex *lex);
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
#include <blue/ds/number.h>
|
||||
#include <blue/ds/string.h>
|
||||
#include <ctype.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/diag/diag.h>
|
||||
#include <mie/diag/highlight.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -66,6 +70,14 @@ static struct mie_lex_symbol_node *get_symbol_node(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct mie_diag *push_diag(struct mie_lex *lex, unsigned long diag_class)
|
||||
{
|
||||
return mie_ctx_push_diag(
|
||||
lex->lex_ctx, lex->lex_source,
|
||||
mie_line_source_get_cursor(lex->lex_source), "builtin",
|
||||
diag_class);
|
||||
}
|
||||
|
||||
static b_string *get_temp_string(struct mie_lex *lex)
|
||||
{
|
||||
if (!lex->lex_temp) {
|
||||
@@ -145,7 +157,7 @@ static struct mie_lex_symbol_node *build_symbol_tree(void)
|
||||
return root;
|
||||
}
|
||||
|
||||
struct mie_lex *mie_lex_create(struct mie_line_source *src)
|
||||
struct mie_lex *mie_lex_create(struct mie_line_source *src, struct mie_ctx *ctx)
|
||||
{
|
||||
struct mie_lex *lex = malloc(sizeof *lex);
|
||||
if (!lex) {
|
||||
@@ -154,6 +166,7 @@ struct mie_lex *mie_lex_create(struct mie_line_source *src)
|
||||
|
||||
memset(lex, 0x0, sizeof *lex);
|
||||
|
||||
lex->lex_ctx = ctx;
|
||||
|
||||
lex->lex_status = MIE_SUCCESS;
|
||||
lex->lex_source = src;
|
||||
@@ -591,6 +604,7 @@ static enum mie_status read_symbol(struct mie_lex *lex)
|
||||
}
|
||||
|
||||
if (!node || node->s_def == NULL) {
|
||||
push_diag(lex, MIE_BUILTIN_E_UNRECOGNISED_TOKEN);
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
@@ -753,6 +767,18 @@ static enum mie_status pump_tokens(struct mie_lex *lex)
|
||||
return read_number(lex, false);
|
||||
}
|
||||
|
||||
struct mie_diag *diag = push_diag(lex, MIE_BUILTIN_E_UNRECOGNISED_TOKEN);
|
||||
mie_diag_push_msg(
|
||||
diag, lex->lex_ctx, "builtin", MIE_BUILTIN_MSG_UNRECOGNISED_TOKEN);
|
||||
const struct mie_file_cell *cursor
|
||||
= mie_line_source_get_cursor(lex->lex_source);
|
||||
unsigned long line = cursor->c_row;
|
||||
const struct mie_diag_highlight hl[] = {
|
||||
{.hl_type = MIE_DIAG_HIGHLIGHT_ERROR,
|
||||
.hl_span = {.s_start = *cursor, .s_end = *cursor}},
|
||||
};
|
||||
const size_t nr_hl = sizeof hl / sizeof hl[0];
|
||||
mie_diag_push_snippet(diag, line, line, NULL, 0, hl, nr_hl);
|
||||
return MIE_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ struct mie_lex {
|
||||
struct mie_line_source *lex_source;
|
||||
enum mie_status lex_status;
|
||||
|
||||
struct mie_ctx *lex_ctx;
|
||||
b_queue lex_queue;
|
||||
|
||||
b_string *lex_temp;
|
||||
|
||||
@@ -260,11 +260,11 @@ bool mie_parser_parse_symbol(struct mie_parser *ctx, enum mie_token_symbol sym)
|
||||
bool mie_parser_parse_linefeed(struct mie_parser *ctx)
|
||||
{
|
||||
struct mie_token *tok = mie_lex_peek(ctx->p_lex);
|
||||
if (tok->tok_type != MIE_TOK_LINEFEED) {
|
||||
if (!MIE_TOKEN_IS(tok, MIE_TOK_LINEFEED)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (tok && tok->tok_type == MIE_TOK_LINEFEED) {
|
||||
while (MIE_TOKEN_IS(tok, MIE_TOK_LINEFEED)) {
|
||||
mie_lex_advance(ctx->p_lex);
|
||||
tok = mie_lex_peek(ctx->p_lex);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user