From da630ce382526a61166a8428ea20a8e547f5f450 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Tue, 13 Jan 2026 22:37:43 +0000 Subject: [PATCH] mie: replace fixed value system with an extensible attribute interface under this new system, dialects can define their own custom attributes, complete with their own print() and parse() callbacks, which can then be used as values in an op's attribute dictionary. alongside custom dialect attributes, the former int, float, and string constant values have been converted to attributes provided by the arith and builtin dialects respectively. the caches for these attributes have also been moved from mie_ctx to their respective dialect data structures. this system will allow new types of attributes to be implemented, including dictionaries, arrays, and references to types themselves (rather than just particular values of a given type). --- mie/attribute/attribute-definition.c | 27 ++ mie/attribute/attribute-map.c | 252 ++++++++++++ .../dialect.h => attribute/attribute.c} | 0 mie/ctx.c | 64 ++-- mie/dialect/arith/arith.c | 56 ++- mie/dialect/arith/attribute/float.c | 85 +++++ mie/dialect/arith/attribute/int.c | 76 ++++ mie/dialect/arith/float-cache.c | 7 +- mie/dialect/arith/float.h | 12 + mie/dialect/arith/int-cache.c | 7 +- mie/dialect/arith/int.h | 12 + mie/dialect/arith/{ => op}/addf.c | 0 mie/dialect/arith/{ => op}/addi.c | 0 mie/dialect/arith/{ => type}/float.c | 40 +- mie/dialect/arith/{ => type}/int.c | 32 +- mie/dialect/builtin/attribute/array.c | 0 mie/dialect/builtin/attribute/string.c | 47 +++ mie/dialect/builtin/attribute/type.c | 0 mie/dialect/builtin/builtin.c | 38 +- mie/dialect/builtin/string-cache.c | 8 +- .../builtin/{ => trait}/isolated-from-above.c | 0 mie/dialect/builtin/{ => type}/string.c | 18 - mie/dialect/cf/cf.c | 2 +- mie/dialect/cf/{ => op}/br-cond.c | 0 mie/dialect/cf/{ => op}/br.c | 0 mie/dialect/dialect.c | 25 +- mie/dialect/func/func.c | 17 +- mie/dialect/func/op/func.c | 18 + mie/dialect/index/index-cache.c | 5 - mie/dialect/index/index.c | 56 ++- mie/dialect/index/type/index.c | 31 ++ mie/dialect/meta/meta.c | 2 +- mie/dialect/meta/{ => op}/source-filename.c | 0 mie/dialect/ptr/{ => op}/load.c | 0 mie/dialect/ptr/{ => op}/store.c | 0 mie/dialect/ptr/ptr.c | 24 +- mie/dialect/ptr/type/ptr.c | 17 + mie/dialect/scf/{ => op}/for.c | 0 mie/dialect/scf/{ => op}/if.c | 0 mie/dialect/scf/{ => op}/yield.c | 0 mie/dialect/scf/scf.c | 2 +- .../select/{ => attribute}/graph-only.c | 0 mie/dialect/select/{ => attribute}/graph-op.c | 0 .../select/{ => attribute}/graph-scope.c | 0 mie/dialect/select/{ => op}/graph.c | 0 mie/dialect/select/select.c | 2 +- .../mie/attribute/attribute-definition.h | 29 ++ mie/include/mie/attribute/attribute-map.h | 44 +++ mie/include/mie/attribute/attribute.h | 10 + mie/include/mie/ctx.h | 16 +- mie/include/mie/dialect/arith.h | 14 +- mie/include/mie/dialect/builtin.h | 7 +- mie/include/mie/dialect/dialect.h | 8 +- mie/include/mie/dialect/index.h | 6 +- mie/include/mie/dialect/memref.h | 13 + mie/include/mie/ir/op.h | 8 +- mie/include/mie/macros.h | 78 +++- mie/include/mie/parse/parser.h | 21 +- mie/include/mie/parse/token.h | 5 +- mie/include/mie/print/printer.h | 6 +- mie/include/mie/status.h | 1 + mie/include/mie/type/type-definition.h | 6 +- mie/include/mie/value.h | 12 - mie/parse/lex.c | 3 + mie/parse/parser.c | 360 ++++++++++-------- mie/print/attribute.c | 10 + mie/print/op.c | 19 +- mie/print/value.c | 11 - 68 files changed, 1219 insertions(+), 450 deletions(-) create mode 100644 mie/attribute/attribute-definition.c create mode 100644 mie/attribute/attribute-map.c rename mie/{dialect/dialect.h => attribute/attribute.c} (100%) create mode 100644 mie/dialect/arith/attribute/float.c create mode 100644 mie/dialect/arith/attribute/int.c create mode 100644 mie/dialect/arith/float.h create mode 100644 mie/dialect/arith/int.h rename mie/dialect/arith/{ => op}/addf.c (100%) rename mie/dialect/arith/{ => op}/addi.c (100%) rename mie/dialect/arith/{ => type}/float.c (69%) rename mie/dialect/arith/{ => type}/int.c (71%) create mode 100644 mie/dialect/builtin/attribute/array.c create mode 100644 mie/dialect/builtin/attribute/string.c create mode 100644 mie/dialect/builtin/attribute/type.c rename mie/dialect/builtin/{ => trait}/isolated-from-above.c (100%) rename mie/dialect/builtin/{ => type}/string.c (57%) rename mie/dialect/cf/{ => op}/br-cond.c (100%) rename mie/dialect/cf/{ => op}/br.c (100%) create mode 100644 mie/dialect/func/op/func.c create mode 100644 mie/dialect/index/type/index.c rename mie/dialect/meta/{ => op}/source-filename.c (100%) rename mie/dialect/ptr/{ => op}/load.c (100%) rename mie/dialect/ptr/{ => op}/store.c (100%) create mode 100644 mie/dialect/ptr/type/ptr.c rename mie/dialect/scf/{ => op}/for.c (100%) rename mie/dialect/scf/{ => op}/if.c (100%) rename mie/dialect/scf/{ => op}/yield.c (100%) rename mie/dialect/select/{ => attribute}/graph-only.c (100%) rename mie/dialect/select/{ => attribute}/graph-op.c (100%) rename mie/dialect/select/{ => attribute}/graph-scope.c (100%) rename mie/dialect/select/{ => op}/graph.c (100%) create mode 100644 mie/include/mie/attribute/attribute-definition.h create mode 100644 mie/include/mie/attribute/attribute-map.h create mode 100644 mie/include/mie/attribute/attribute.h create mode 100644 mie/include/mie/dialect/memref.h delete mode 100644 mie/include/mie/value.h create mode 100644 mie/print/attribute.c delete mode 100644 mie/print/value.c diff --git a/mie/attribute/attribute-definition.c b/mie/attribute/attribute-definition.c new file mode 100644 index 0000000..ea13fb6 --- /dev/null +++ b/mie/attribute/attribute-definition.c @@ -0,0 +1,27 @@ +#include +#include +#include + +struct mie_attribute_definition *mie_attribute_definition_create( + struct mie_dialect *parent, const char *name) +{ + struct mie_attribute_definition *out = malloc(sizeof *out); + if (!out) { + return NULL; + } + + memset(out, 0x0, sizeof *out); + + out->a_name = b_strdup(name); + if (!out->a_name) { + free(out); + return NULL; + } + + out->a_parent = parent; + + b_rope name_rope = B_ROPE_CSTR(name); + mie_id_map_put(&parent->d_attributes, &out->a_id, &name_rope); + + return out; +} diff --git a/mie/attribute/attribute-map.c b/mie/attribute/attribute-map.c new file mode 100644 index 0000000..1d6d4ba --- /dev/null +++ b/mie/attribute/attribute-map.c @@ -0,0 +1,252 @@ +#include +#include +#include +#include + +enum attribute_map_entry_type { + ATTRMAP_ENTRY_NONE = 0, + ATTRMAP_ENTRY_BUCKET, + ATTRMAP_ENTRY_ITEM, +}; + +struct attribute_map_entry { + enum attribute_map_entry_type e_type; + uint64_t e_hash; + union { + b_btree_node e_node; + b_queue_entry e_entry; + }; +}; + +struct attribute_map_bucket { + struct attribute_map_entry b_base; + b_queue b_items; +}; + +struct attribute_map_item { + struct attribute_map_entry i_base; + char *i_name; + const struct mie_attribute *i_value; +}; + +static B_BTREE_DEFINE_SIMPLE_INSERT( + struct attribute_map_entry, e_node, e_hash, put_entry); +static B_BTREE_DEFINE_SIMPLE_GET( + struct attribute_map_entry, uint64_t, e_node, e_hash, get_entry); + +void mie_attribute_map_init(struct mie_attribute_map *map) +{ + memset(map, 0x0, sizeof *map); +} + +void mie_attribute_map_cleanup(struct mie_attribute_map *map) +{ + /* TODO */ +} + +static const struct mie_attribute *get_attribute_from_item( + const struct attribute_map_item *item, const char *name) +{ + if (!strcmp(item->i_name, name)) { + return item->i_value; + } + + return NULL; +} + +static const struct mie_attribute *get_attribute_from_bucket( + const struct attribute_map_bucket *bucket, const char *name) +{ + b_queue_entry *cur = b_queue_first(&bucket->b_items); + while (cur) { + const struct attribute_map_item *item = b_unbox( + const struct attribute_map_item, cur, i_base.e_entry); + + if (!strcmp(item->i_name, name)) { + return item->i_value; + } + + cur = b_queue_next(cur); + } + + return NULL; +} + +static const struct mie_attribute *get_attribute_from_entry( + const struct attribute_map_entry *entry, const char *name) +{ + switch (entry->e_type) { + case ATTRMAP_ENTRY_ITEM: + return get_attribute_from_item( + (const struct attribute_map_item *)entry, name); + case ATTRMAP_ENTRY_BUCKET: + return get_attribute_from_bucket( + (const struct attribute_map_bucket *)entry, name); + default: + return NULL; + } +} + +const struct mie_attribute *mie_attribute_map_get( + const struct mie_attribute_map *map, const char *name) +{ + uint64_t name_hash = b_hash_cstr(name); + struct attribute_map_entry *entry = get_entry(&map->m_entries, name_hash); + if (!entry) { + return NULL; + } + + return get_attribute_from_entry(entry, name); +} + +static struct attribute_map_bucket *convert_item_to_bucket( + struct mie_attribute_map *map, struct attribute_map_item *item) +{ + struct attribute_map_bucket *bucket = malloc(sizeof *bucket); + if (!bucket) { + return NULL; + } + + b_btree_delete(&map->m_entries, &item->i_base.e_node); + memset(bucket, 0x0, sizeof *bucket); + + bucket->b_base.e_type = ATTRMAP_ENTRY_BUCKET; + bucket->b_base.e_hash = item->i_base.e_hash; + + b_queue_push_back(&bucket->b_items, &item->i_base.e_entry); + put_entry(&map->m_entries, &bucket->b_base); + + return bucket; +} + +static struct attribute_map_item *create_item( + const char *name, uint64_t name_hash, const struct mie_attribute *attrib) +{ + struct attribute_map_item *out = malloc(sizeof *out); + if (!out) { + return NULL; + } + + memset(out, 0x0, sizeof *out); + + out->i_value = attrib; + out->i_base.e_type = ATTRMAP_ENTRY_ITEM; + out->i_base.e_hash = name_hash; + out->i_name = b_strdup(name); + if (!out->i_name) { + free(out); + return NULL; + } + + return out; +} + +enum mie_status mie_attribute_map_put( + struct mie_attribute_map *map, const char *name, + const struct mie_attribute *value, enum mie_attribute_map_flags flags) +{ + uint64_t name_hash = b_hash_cstr(name); + struct attribute_map_entry *entry = get_entry(&map->m_entries, name_hash); + struct attribute_map_item *item = NULL; + struct attribute_map_bucket *bucket = NULL; + + if (!entry) { + item = create_item(name, name_hash, value); + if (!item) { + return MIE_ERR_NO_MEMORY; + } + + put_entry(&map->m_entries, &item->i_base); + return MIE_SUCCESS; + } + + if (entry->e_type == ATTRMAP_ENTRY_ITEM) { + item = (struct attribute_map_item *)entry; + bucket = convert_item_to_bucket(map, item); + } else { + bucket = (struct attribute_map_bucket *)entry; + } + + item = create_item(name, name_hash, value); + if (!item) { + return MIE_ERR_NO_MEMORY; + } + + b_queue_push_back(&bucket->b_items, &item->i_base.e_entry); + return MIE_SUCCESS; +} + +enum mie_status mie_attribute_map_iterator_begin( + struct mie_attribute_map_iterator *it, const struct mie_attribute_map *map) +{ + memset(it, 0x0, sizeof *it); + it->_n = b_btree_first(&map->m_entries); + if (!it->_n) { + return MIE_ERR_NO_DATA; + } + + struct attribute_map_entry *entry + = b_unbox(struct attribute_map_entry, it->_n, e_node); + struct attribute_map_item *item = NULL; + struct attribute_map_bucket *bucket = NULL; + + switch (entry->e_type) { + case ATTRMAP_ENTRY_ITEM: + item = (struct attribute_map_item *)entry; + it->it_name = item->i_name; + it->it_value = item->i_value; + return MIE_SUCCESS; + case ATTRMAP_ENTRY_BUCKET: + bucket = (struct attribute_map_bucket *)entry; + it->_e = b_queue_first(&bucket->b_items); + item = b_unbox(struct attribute_map_item, it->_e, i_base.e_entry); + it->it_name = item->i_name; + it->it_value = item->i_value; + return MIE_SUCCESS; + default: + return MIE_ERR_BAD_STATE; + } +} + +enum mie_status mie_attribute_map_iterator_move_next( + struct mie_attribute_map_iterator *it) +{ + struct attribute_map_entry *next_entry = NULL; + struct attribute_map_item *next_item = NULL; + struct attribute_map_bucket *next_bucket = NULL; + + if (it->_e) { + it->_e = b_queue_next(it->_e); + next_entry = b_unbox(struct attribute_map_entry, it->_e, e_entry); + } else if (it->_n) { + it->_n = b_btree_next(it->_n); + next_entry = b_unbox(struct attribute_map_entry, it->_n, e_node); + } else { + memset(it, 0x0, sizeof *it); + return MIE_ERR_NO_DATA; + } + + if (!next_entry) { + memset(it, 0x0, sizeof *it); + return MIE_ERR_NO_DATA; + } + + switch (next_entry->e_type) { + case ATTRMAP_ENTRY_ITEM: + next_item = (struct attribute_map_item *)next_entry; + break; + case ATTRMAP_ENTRY_BUCKET: + next_bucket = (struct attribute_map_bucket *)next_item; + it->_e = b_queue_first(&next_bucket->b_items); + next_item = b_unbox( + struct attribute_map_item, it->_e, i_base.e_entry); + break; + default: + memset(it, 0x0, sizeof *it); + return MIE_ERR_BAD_STATE; + } + + it->it_name = next_item->i_name; + it->it_value = next_item->i_value; + return MIE_SUCCESS; +} diff --git a/mie/dialect/dialect.h b/mie/attribute/attribute.c similarity index 100% rename from mie/dialect/dialect.h rename to mie/attribute/attribute.c diff --git a/mie/ctx.c b/mie/ctx.c index dd476ab..f0ca476 100644 --- a/mie/ctx.c +++ b/mie/ctx.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,14 @@ MIE_ID(0xf5, 0x4e, 0xc5, 0x8c, 0xc0, 0x1e, 0x48, 0x47, 0xb5, 0xf4, \ 0x7b, 0xb9, 0x6b, 0x47, 0xca, 0x48) +#define TRAIT_NS_ID \ + MIE_ID(0xeb, 0x02, 0xcc, 0xe5, 0x32, 0x80, 0x4e, 0xc3, 0x84, 0xf3, \ + 0xc0, 0x07, 0x72, 0xf0, 0x4c, 0xca) + +#define ATTRIBUTE_NS_ID \ + MIE_ID(0xc6, 0x94, 0x38, 0x34, 0xdb, 0x08, 0x45, 0xc7, 0xb9, 0x89, \ + 0x69, 0x82, 0x7a, 0x9d, 0x42, 0xd8) + struct mie_ctx *mie_ctx_create(void) { struct mie_ctx *out = malloc(sizeof *out); @@ -41,10 +50,11 @@ struct mie_ctx *mie_ctx_create(void) mie_id types_ns = TYPE_NS_ID; mie_id_map_init(&out->ctx_types, &types_ns); - out->ctx_ints = mie_int_cache_create(); - out->ctx_floats = mie_float_cache_create(); - out->ctx_indices = mie_index_cache_create(); - out->ctx_strings = mie_string_cache_create(); + mie_id traits_ns = TRAIT_NS_ID; + mie_id_map_init(&out->ctx_traits, &traits_ns); + + mie_id attributes_ns = ATTRIBUTE_NS_ID; + mie_id_map_init(&out->ctx_attributes, &attributes_ns); return out; } @@ -151,6 +161,30 @@ const struct mie_trait_definition *mie_ctx_get_trait_definition( return b_unbox(struct mie_trait_definition, target, tr_id); } +const struct mie_attribute_definition *mie_ctx_get_attribute_definition( + const struct mie_ctx *ctx, const char *dialect_name, + const char *attribute_name) +{ + b_rope dialect_name_rope = B_ROPE_CSTR(dialect_name); + mie_id id; + mie_id_init_ns( + &id, mie_id_map_get_ns(&ctx->ctx_dialects), &dialect_name_rope); + + mie_id *target = mie_id_map_get(&ctx->ctx_dialects, &id); + struct mie_dialect *dialect = b_unbox(struct mie_dialect, target, d_id); + if (!dialect) { + return NULL; + } + + b_rope attribute_name_rope = B_ROPE_CSTR(attribute_name); + mie_id_init_ns( + &id, mie_id_map_get_ns(&dialect->d_attributes), + &attribute_name_rope); + target = mie_id_map_get(&dialect->d_attributes, &id); + + return b_unbox(struct mie_attribute_definition, target, a_id); +} + struct mie_type *mie_ctx_get_type( struct mie_ctx *ctx, const char *dialect_name, const char *type_name) { @@ -299,25 +333,3 @@ struct mie_type *mie_ctx_get_function_type( mie_id_map_put_id(&ctx->ctx_types, &new_type->func_base.ty_id); return (struct mie_type *)new_type; } - -struct mie_value *mie_ctx_get_int(struct mie_ctx *ctx, long long val, size_t nr_bits) -{ - return (struct mie_value *)mie_int_cache_get( - ctx->ctx_ints, ctx, val, nr_bits); -} - -struct mie_value *mie_ctx_get_float(struct mie_ctx *ctx, double val, size_t nr_bits) -{ - return (struct mie_value *)mie_float_cache_get( - ctx->ctx_floats, ctx, val, nr_bits); -} - -struct mie_value *mie_ctx_get_string(struct mie_ctx *ctx, const char *s) -{ - return (struct mie_value *)mie_string_cache_get(ctx->ctx_strings, ctx, s); -} - -struct mie_value *mie_ctx_get_index(struct mie_ctx *ctx, size_t val) -{ - return (struct mie_value *)mie_index_cache_get(ctx->ctx_indices, ctx, val); -} diff --git a/mie/dialect/arith/arith.c b/mie/dialect/arith/arith.c index 0ee75bd..d21c60f 100644 --- a/mie/dialect/arith/arith.c +++ b/mie/dialect/arith/arith.c @@ -1,9 +1,63 @@ +#include +#include #include #include -MIE_DIALECT_BEGIN(mie_arith, "arith") +struct arith_dialect { + struct mie_dialect d_base; + struct mie_int_cache *ctx_ints; + struct mie_float_cache *ctx_floats; +}; + +static enum mie_status init(struct mie_dialect *d) +{ + struct arith_dialect *dialect = (struct arith_dialect *)d; + dialect->ctx_ints = mie_int_cache_create(); + dialect->ctx_floats = mie_float_cache_create(); + return MIE_SUCCESS; +} + +static enum mie_status cleanup(struct mie_dialect *d) +{ + struct arith_dialect *dialect = (struct arith_dialect *)d; + mie_int_cache_destroy(dialect->ctx_ints); + mie_float_cache_destroy(dialect->ctx_floats); + return MIE_SUCCESS; +} + +struct mie_attribute *mie_ctx_get_int( + struct mie_ctx *ctx, long long val, size_t nr_bits) +{ + struct arith_dialect *dialect + = (struct arith_dialect *)mie_ctx_get_dialect(ctx, "arith"); + if (!dialect) { + return NULL; + } + + return (struct mie_attribute *)mie_int_cache_get( + dialect->ctx_ints, ctx, val, nr_bits); +} + +struct mie_attribute *mie_ctx_get_float( + struct mie_ctx *ctx, double val, size_t nr_bits) +{ + struct arith_dialect *dialect + = (struct arith_dialect *)mie_ctx_get_dialect(ctx, "arith"); + if (!dialect) { + return NULL; + } + + return (struct mie_attribute *)mie_float_cache_get( + dialect->ctx_floats, ctx, val, nr_bits); +} + +MIE_DIALECT_BEGIN(mie_arith, struct arith_dialect, "arith") + MIE_DIALECT_INIT(init); + MIE_DIALECT_CLEANUP(cleanup); MIE_DIALECT_ADD_TYPE(mie_arith_int); MIE_DIALECT_ADD_TYPE(mie_arith_float); MIE_DIALECT_ADD_OP(mie_arith_addi); MIE_DIALECT_ADD_OP(mie_arith_addf); + MIE_DIALECT_ADD_ATTRIBUTE(mie_arith_int); + MIE_DIALECT_ADD_ATTRIBUTE(mie_arith_float); MIE_DIALECT_END() diff --git a/mie/dialect/arith/attribute/float.c b/mie/dialect/arith/attribute/float.c new file mode 100644 index 0000000..faf08b5 --- /dev/null +++ b/mie/dialect/arith/attribute/float.c @@ -0,0 +1,85 @@ +#include "../float.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static enum mie_status print( + const struct mie_attribute *value, struct mie_printer *out) +{ + const struct mie_float *float_val = (const struct mie_float *)value; + const struct float_type *float_ty + = (const struct float_type *)float_val->f_type; + if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) { + b_stream_write_string(out->p_stream, "#arith.float<", NULL); + } + + switch (float_ty->f_width) { + case MIE_FLOAT_32: + b_stream_write_fmt( + out->p_stream, NULL, "%f : f%zu", float_val->f_val.v_32, + float_ty->f_width); + break; + case MIE_FLOAT_64: + b_stream_write_fmt( + out->p_stream, NULL, "%lf : f%zu", + float_val->f_val.v_64, float_ty->f_width); + break; + default: + b_stream_write_fmt( + out->p_stream, NULL, "NaN : f%zu", float_ty->f_width); + break; + } + + if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) { + b_stream_write_string(out->p_stream, ">", NULL); + } + + return MIE_SUCCESS; +} + +static enum mie_status parse( + struct mie_parser *ctx, const struct mie_attribute **out) +{ + double value = 0; + struct mie_file_span span; + + if (!mie_parser_parse_float(ctx, &value, &span)) { + return false; + } + + if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) { + return false; + } + + const struct mie_type *type = NULL; + if (!mie_parser_parse_type(ctx, &type)) { + return false; + } + + size_t width = mie_arith_float_type_get_width(type); + if (width == (size_t)-1) { + return false; + } + + struct mie_attribute *v + = mie_ctx_get_float(mie_parser_get_mie_ctx(ctx), value, width); + if (!v) { + return false; + } + + *out = v; + return true; +} + +MIE_ATTRIBUTE_DEFINITION_BEGIN(mie_arith_float, "float") + MIE_ATTRIBUTE_DEFINITION_STRUCT(struct mie_float); + MIE_ATTRIBUTE_DEFINITION_PRINT(print); + MIE_ATTRIBUTE_DEFINITION_PARSE(parse); +MIE_ATTRIBUTE_DEFINITION_END() diff --git a/mie/dialect/arith/attribute/int.c b/mie/dialect/arith/attribute/int.c new file mode 100644 index 0000000..5c78e15 --- /dev/null +++ b/mie/dialect/arith/attribute/int.c @@ -0,0 +1,76 @@ +#include "../int.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static enum mie_status print( + const struct mie_attribute *value, struct mie_printer *out) +{ + const struct mie_int *int_val = (const struct mie_int *)value; + const struct int_type *int_ty = (const struct int_type *)int_val->i_type; + if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) { + b_stream_write_string(out->p_stream, "#arith.int<", NULL); + } + + if (int_ty->i_width <= 64) { + b_stream_write_fmt( + out->p_stream, NULL, "%zu : i%zu", + int_val->i_val.v_small, int_ty->i_width); + } else { + b_stream_write_fmt( + out->p_stream, NULL, "INF : i%zu", int_ty->i_width); + } + + if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) { + b_stream_write_string(out->p_stream, ">", NULL); + } + + return MIE_SUCCESS; +} + +static enum mie_status parse( + struct mie_parser *ctx, const struct mie_attribute **out) +{ + long long value = 0; + struct mie_file_span span; + + if (!mie_parser_parse_int(ctx, &value, &span)) { + return false; + } + + if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) { + return false; + } + + const struct mie_type *type = NULL; + if (!mie_parser_parse_type(ctx, &type)) { + return false; + } + + size_t width = mie_arith_int_type_get_width(type); + if (width == (size_t)-1) { + return false; + } + + struct mie_attribute *v + = mie_ctx_get_int(mie_parser_get_mie_ctx(ctx), value, width); + if (!v) { + return false; + } + + *out = v; + return true; +} + +MIE_ATTRIBUTE_DEFINITION_BEGIN(mie_arith_int, "int") + MIE_ATTRIBUTE_DEFINITION_STRUCT(struct mie_int); + MIE_ATTRIBUTE_DEFINITION_PRINT(print); + MIE_ATTRIBUTE_DEFINITION_PARSE(parse); +MIE_ATTRIBUTE_DEFINITION_END() diff --git a/mie/dialect/arith/float-cache.c b/mie/dialect/arith/float-cache.c index 91f24ac..38460d8 100644 --- a/mie/dialect/arith/float-cache.c +++ b/mie/dialect/arith/float-cache.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -145,8 +146,10 @@ static struct float_width_cache_entry *float_width_cache_entry_create( return NULL; } - out->e_value.f_base.v_type = mie_arith_float_get_type(ctx, width); - if (!out->e_value.f_base.v_type) { + out->e_value.f_base.a_def + = mie_ctx_get_attribute_definition(ctx, "arith", "float"); + out->e_value.f_type = mie_arith_float_get_type(ctx, width); + if (!out->e_value.f_type) { free(out); return NULL; } diff --git a/mie/dialect/arith/float.h b/mie/dialect/arith/float.h new file mode 100644 index 0000000..26855b5 --- /dev/null +++ b/mie/dialect/arith/float.h @@ -0,0 +1,12 @@ +#ifndef _ARITH_FLOAT_H_ +#define _ARITH_FLOAT_H_ + +#include +#include + +struct float_type { + struct mie_type f_base; + size_t f_width; +}; + +#endif diff --git a/mie/dialect/arith/int-cache.c b/mie/dialect/arith/int-cache.c index f174613..788ec4e 100644 --- a/mie/dialect/arith/int-cache.c +++ b/mie/dialect/arith/int-cache.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -70,9 +71,11 @@ static struct int_width_cache_entry *int_width_cache_entry_create( memset(out, 0x0, sizeof *out); + out->e_value.i_base.a_def + = mie_ctx_get_attribute_definition(ctx, "arith", "int"); out->e_value.i_val.v_small = value; - out->e_value.i_base.v_type = mie_arith_int_get_type(ctx, width); - if (!out->e_value.i_base.v_type) { + out->e_value.i_type = mie_arith_int_get_type(ctx, width); + if (!out->e_value.i_type) { free(out); return NULL; } diff --git a/mie/dialect/arith/int.h b/mie/dialect/arith/int.h new file mode 100644 index 0000000..ed19923 --- /dev/null +++ b/mie/dialect/arith/int.h @@ -0,0 +1,12 @@ +#ifndef _ARITH_INT_H_ +#define _ARITH_INT_H_ + +#include +#include + +struct int_type { + struct mie_type i_base; + size_t i_width; +}; + +#endif diff --git a/mie/dialect/arith/addf.c b/mie/dialect/arith/op/addf.c similarity index 100% rename from mie/dialect/arith/addf.c rename to mie/dialect/arith/op/addf.c diff --git a/mie/dialect/arith/addi.c b/mie/dialect/arith/op/addi.c similarity index 100% rename from mie/dialect/arith/addi.c rename to mie/dialect/arith/op/addi.c diff --git a/mie/dialect/arith/float.c b/mie/dialect/arith/type/float.c similarity index 69% rename from mie/dialect/arith/float.c rename to mie/dialect/arith/type/float.c index 367be89..665e466 100644 --- a/mie/dialect/arith/float.c +++ b/mie/dialect/arith/type/float.c @@ -1,3 +1,5 @@ +#include "../float.h" + #include #include #include @@ -6,37 +8,6 @@ #include #include #include -#include - -struct float_type { - struct mie_type f_base; - size_t f_width; -}; - -static enum mie_status value_print( - const struct mie_value *value, struct mie_printer *out) -{ - struct float_type *float_ty = (struct float_type *)value->v_type; - struct mie_float *float_val = (struct mie_float *)value; - switch (float_ty->f_width) { - case MIE_FLOAT_32: - b_stream_write_fmt( - out->p_stream, NULL, "%f : f%zu", float_val->f_val.v_32, - float_ty->f_width); - break; - case MIE_FLOAT_64: - b_stream_write_fmt( - out->p_stream, NULL, "%lf : f%zu", - float_val->f_val.v_64, float_ty->f_width); - break; - default: - b_stream_write_fmt( - out->p_stream, NULL, "NaN : f%zu", float_ty->f_width); - break; - } - - return MIE_SUCCESS; -} struct mie_type *mie_arith_float_get_type(struct mie_ctx *ctx, size_t bit_width) { @@ -91,15 +62,13 @@ static enum mie_status print(const struct mie_type *ty, struct mie_printer *out) b_stream_write_fmt( out->p_stream, NULL, (out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "f%zu" - : "arith.float<%zu>", + : "!arith.float<%zu>", float_type->f_width); return MIE_SUCCESS; } -static enum mie_status parse( - const struct mie_type_definition *def, struct mie_parser *parser, - struct mie_type **out) +static enum mie_status parse(struct mie_parser *parser, const struct mie_type **out) { return MIE_SUCCESS; } @@ -109,5 +78,4 @@ MIE_TYPE_DEFINITION_BEGIN(mie_arith_float, "float") MIE_TYPE_DEFINITION_STRUCT(struct float_type); MIE_TYPE_DEFINITION_PRINT(print); MIE_TYPE_DEFINITION_PARSE(parse); - MIE_TYPE_DEFINITION_VALUE_PRINT(value_print); MIE_TYPE_DEFINITION_END() diff --git a/mie/dialect/arith/int.c b/mie/dialect/arith/type/int.c similarity index 71% rename from mie/dialect/arith/int.c rename to mie/dialect/arith/type/int.c index 9929d3b..26d7307 100644 --- a/mie/dialect/arith/int.c +++ b/mie/dialect/arith/type/int.c @@ -1,3 +1,5 @@ +#include "../int.h" + #include #include #include @@ -6,29 +8,6 @@ #include #include #include -#include - -struct int_type { - struct mie_type i_base; - size_t i_width; -}; - -static enum mie_status value_print( - const struct mie_value *value, struct mie_printer *out) -{ - struct int_type *int_ty = (struct int_type *)value->v_type; - struct mie_int *int_val = (struct mie_int *)value; - if (int_ty->i_width <= 64) { - b_stream_write_fmt( - out->p_stream, NULL, "%zu : i%zu", - int_val->i_val.v_small, int_ty->i_width); - } else { - b_stream_write_fmt( - out->p_stream, NULL, "INF : i%zu", int_ty->i_width); - } - - return MIE_SUCCESS; -} struct mie_type *mie_arith_int_get_type(struct mie_ctx *ctx, size_t bit_width) { @@ -82,15 +61,13 @@ static enum mie_status print(const struct mie_type *ty, struct mie_printer *out) const struct int_type *int_type = (const struct int_type *)ty; b_stream_write_fmt( out->p_stream, NULL, - (out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "i%zu" : "arith.int<%zu>", + (out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "i%zu" : "!arith.int<%zu>", int_type->i_width); return MIE_SUCCESS; } -static enum mie_status parse( - const struct mie_type_definition *def, struct mie_parser *parser, - struct mie_type **out) +static enum mie_status parse(struct mie_parser *parser, const struct mie_type **out) { return MIE_SUCCESS; } @@ -100,5 +77,4 @@ MIE_TYPE_DEFINITION_BEGIN(mie_arith_int, "int") MIE_TYPE_DEFINITION_STRUCT(struct int_type); MIE_TYPE_DEFINITION_PRINT(print); MIE_TYPE_DEFINITION_PARSE(parse); - MIE_TYPE_DEFINITION_VALUE_PRINT(value_print); MIE_TYPE_DEFINITION_END() diff --git a/mie/dialect/builtin/attribute/array.c b/mie/dialect/builtin/attribute/array.c new file mode 100644 index 0000000..e69de29 diff --git a/mie/dialect/builtin/attribute/string.c b/mie/dialect/builtin/attribute/string.c new file mode 100644 index 0000000..cf522c2 --- /dev/null +++ b/mie/dialect/builtin/attribute/string.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include +#include +#include + +static enum mie_status print( + const struct mie_attribute *value, struct mie_printer *out) +{ + const struct mie_string *str = (const struct mie_string *)value; + if (out->p_flags & MIE_PRINT_F_ABBREVIATED) { + b_stream_write_fmt(out->p_stream, NULL, "\"%s\"", str->str_val); + } else { + b_stream_write_fmt( + out->p_stream, NULL, "#builtin.string<\"%s\">", + str->str_val); + } + return MIE_SUCCESS; +} + +static enum mie_status parse( + struct mie_parser *ctx, const struct mie_attribute **out) +{ + b_string *str = mie_parser_get_tempstr(ctx); + struct mie_file_span span; + if (!mie_parser_parse_string(ctx, str, &span)) { + return false; + } + + struct mie_attribute *v = mie_ctx_get_string( + mie_parser_get_mie_ctx(ctx), b_string_ptr(str)); + + if (!v) { + return false; + } + + *out = v; + return true; +} + +MIE_ATTRIBUTE_DEFINITION_BEGIN(mie_builtin_string, "string") + MIE_ATTRIBUTE_DEFINITION_STRUCT(struct mie_string); + MIE_ATTRIBUTE_DEFINITION_PRINT(print); + MIE_ATTRIBUTE_DEFINITION_PARSE(parse); +MIE_ATTRIBUTE_DEFINITION_END(); diff --git a/mie/dialect/builtin/attribute/type.c b/mie/dialect/builtin/attribute/type.c new file mode 100644 index 0000000..e69de29 diff --git a/mie/dialect/builtin/builtin.c b/mie/dialect/builtin/builtin.c index 115205d..49d249b 100644 --- a/mie/dialect/builtin/builtin.c +++ b/mie/dialect/builtin/builtin.c @@ -1,7 +1,43 @@ +#include +#include #include #include -MIE_DIALECT_BEGIN(mie_builtin, "builtin") +struct builtin_dialect { + struct mie_dialect d_base; + struct mie_string_cache *ctx_strings; +}; + +static enum mie_status init(struct mie_dialect *d) +{ + struct builtin_dialect *dialect = (struct builtin_dialect *)d; + dialect->ctx_strings = mie_string_cache_create(); + return MIE_SUCCESS; +} + +static enum mie_status cleanup(struct mie_dialect *d) +{ + struct builtin_dialect *dialect = (struct builtin_dialect *)d; + mie_string_cache_destroy(dialect->ctx_strings); + return MIE_SUCCESS; +} + +struct mie_attribute *mie_ctx_get_string(struct mie_ctx *ctx, const char *s) +{ + struct builtin_dialect *dialect + = (struct builtin_dialect *)mie_ctx_get_dialect(ctx, "builtin"); + if (!dialect) { + return NULL; + } + + return (struct mie_attribute *)mie_string_cache_get( + dialect->ctx_strings, ctx, s); +} + +MIE_DIALECT_BEGIN(mie_builtin, struct builtin_dialect, "builtin") + MIE_DIALECT_INIT(init); + MIE_DIALECT_CLEANUP(cleanup); MIE_DIALECT_ADD_TYPE(mie_builtin_string); + MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_string); MIE_DIALECT_ADD_TRAIT(mie_builtin_isolated_from_above); MIE_DIALECT_END() diff --git a/mie/dialect/builtin/string-cache.c b/mie/dialect/builtin/string-cache.c index 88fc84c..0106861 100644 --- a/mie/dialect/builtin/string-cache.c +++ b/mie/dialect/builtin/string-cache.c @@ -17,12 +17,8 @@ static struct mie_string *mie_string_create( return NULL; } - out->str_base.v_type = mie_ctx_get_type(ctx, "builtin", "string"); - if (!out->str_base.v_type) { - free(out); - return NULL; - } - + out->str_base.a_def + = mie_ctx_get_attribute_definition(ctx, "builtin", "string"); out->str_val = b_strdup(s); if (!out->str_val) { return NULL; diff --git a/mie/dialect/builtin/isolated-from-above.c b/mie/dialect/builtin/trait/isolated-from-above.c similarity index 100% rename from mie/dialect/builtin/isolated-from-above.c rename to mie/dialect/builtin/trait/isolated-from-above.c diff --git a/mie/dialect/builtin/string.c b/mie/dialect/builtin/type/string.c similarity index 57% rename from mie/dialect/builtin/string.c rename to mie/dialect/builtin/type/string.c index f1cdfd2..b81dcb4 100644 --- a/mie/dialect/builtin/string.c +++ b/mie/dialect/builtin/type/string.c @@ -6,15 +6,6 @@ #include #include #include -#include - -static enum mie_status value_print( - const struct mie_value *value, struct mie_printer *out) -{ - const struct mie_string *str = (const struct mie_string *)value; - b_stream_write_fmt(out->p_stream, NULL, "\"%s\"", str->str_val); - return MIE_SUCCESS; -} static void type_init( const struct mie_type_definition *type_info, struct mie_type *type) @@ -27,17 +18,8 @@ static enum mie_status print(const struct mie_type *ty, struct mie_printer *out) return MIE_SUCCESS; } -static enum mie_status parse( - const struct mie_type_definition *def, struct mie_parser *parser, - struct mie_type **out) -{ - return MIE_SUCCESS; -} - MIE_TYPE_DEFINITION_BEGIN(mie_builtin_string, "string") MIE_TYPE_DEFINITION_STRUCT(struct mie_type); MIE_TYPE_DEFINITION_INIT(type_init); MIE_TYPE_DEFINITION_PRINT(print); - MIE_TYPE_DEFINITION_PARSE(parse); - MIE_TYPE_DEFINITION_VALUE_PRINT(value_print); MIE_TYPE_DEFINITION_END() diff --git a/mie/dialect/cf/cf.c b/mie/dialect/cf/cf.c index 2713947..94e7d6e 100644 --- a/mie/dialect/cf/cf.c +++ b/mie/dialect/cf/cf.c @@ -1,7 +1,7 @@ #include #include -MIE_DIALECT_BEGIN(mie_cf, "cf") +MIE_DIALECT_BEGIN(mie_cf, struct mie_dialect, "cf") MIE_DIALECT_ADD_OP(mie_cf_br); MIE_DIALECT_ADD_OP(mie_cf_br_cond); MIE_DIALECT_END() diff --git a/mie/dialect/cf/br-cond.c b/mie/dialect/cf/op/br-cond.c similarity index 100% rename from mie/dialect/cf/br-cond.c rename to mie/dialect/cf/op/br-cond.c diff --git a/mie/dialect/cf/br.c b/mie/dialect/cf/op/br.c similarity index 100% rename from mie/dialect/cf/br.c rename to mie/dialect/cf/op/br.c diff --git a/mie/dialect/dialect.c b/mie/dialect/dialect.c index b605245..fbacad9 100644 --- a/mie/dialect/dialect.c +++ b/mie/dialect/dialect.c @@ -11,14 +11,27 @@ MIE_ID(0xb9, 0x97, 0xcf, 0xd3, 0x81, 0xd4, 0x45, 0x06, 0x9b, 0x44, \ 0x05, 0x9f, 0xb4, 0x76, 0xf1, 0x2d) -struct mie_dialect *mie_dialect_create(struct mie_ctx *ctx, const char *name) +#define TRAIT_NS_ID \ + MIE_ID(0x5a, 0x11, 0x68, 0x8e, 0x21, 0x1d, 0x4d, 0x5f, 0xb8, 0x6b, \ + 0x39, 0x73, 0xb0, 0x1f, 0xce, 0xf7) + +#define ATTRIBUTE_NS_ID \ + MIE_ID(0x86, 0x76, 0xcb, 0xfb, 0xc8, 0xe5, 0x40, 0x7d, 0xa3, 0x84, \ + 0x93, 0xe3, 0xa5, 0x29, 0x74, 0xfe) + +struct mie_dialect *mie_dialect_create( + struct mie_ctx *ctx, const char *name, size_t size) { - struct mie_dialect *out = malloc(sizeof *out); + if (size < sizeof(struct mie_dialect)) { + return NULL; + } + + struct mie_dialect *out = malloc(size); if (!out) { return NULL; } - memset(out, 0x0, sizeof *out); + memset(out, 0x0, size); out->d_name = b_strdup(name); if (!out->d_name) { @@ -32,6 +45,12 @@ struct mie_dialect *mie_dialect_create(struct mie_ctx *ctx, const char *name) mie_id type_ns = TYPE_NS_ID; mie_id_map_init(&out->d_types, &type_ns); + mie_id trait_ns = TRAIT_NS_ID; + mie_id_map_init(&out->d_traits, &trait_ns); + + mie_id attribute_ns = ATTRIBUTE_NS_ID; + mie_id_map_init(&out->d_attributes, &attribute_ns); + b_rope name_rope = B_ROPE_CSTR(name); mie_id_map_put(&ctx->ctx_dialects, &out->d_id, &name_rope); diff --git a/mie/dialect/func/func.c b/mie/dialect/func/func.c index f3134d8..ff3f881 100644 --- a/mie/dialect/func/func.c +++ b/mie/dialect/func/func.c @@ -2,21 +2,6 @@ #include #include -static enum mie_status print(const struct mie_op *op, b_stream *out) -{ - return MIE_SUCCESS; -} - -static enum mie_status parse(struct mie_parser *parser, struct mie_op *out) -{ - return MIE_SUCCESS; -} - -MIE_OP_DEFINITION_BEGIN(mie_func_func, "func") - MIE_OP_DEFINITION_PRINT(print); - MIE_OP_DEFINITION_PARSE(parse); -MIE_OP_DEFINITION_END() - -MIE_DIALECT_BEGIN(mie_func, "func") +MIE_DIALECT_BEGIN(mie_func, struct mie_dialect, "func") MIE_DIALECT_ADD_OP(mie_func_func); MIE_DIALECT_END() diff --git a/mie/dialect/func/op/func.c b/mie/dialect/func/op/func.c new file mode 100644 index 0000000..5a9ca29 --- /dev/null +++ b/mie/dialect/func/op/func.c @@ -0,0 +1,18 @@ +#include +#include +#include + +static enum mie_status print(const struct mie_op *op, b_stream *out) +{ + return MIE_SUCCESS; +} + +static enum mie_status parse(struct mie_parser *parser, struct mie_op *out) +{ + return MIE_SUCCESS; +} + +MIE_OP_DEFINITION_BEGIN(mie_func_func, "func") + MIE_OP_DEFINITION_PRINT(print); + MIE_OP_DEFINITION_PARSE(parse); +MIE_OP_DEFINITION_END() diff --git a/mie/dialect/index/index-cache.c b/mie/dialect/index/index-cache.c index ede58d7..8703ba5 100644 --- a/mie/dialect/index/index-cache.c +++ b/mie/dialect/index/index-cache.c @@ -29,11 +29,6 @@ static struct index_cache_entry *index_cache_entry_create( memset(out, 0x0, sizeof *out); out->e_value.i_value = val; - out->e_value.i_base.v_type = mie_ctx_get_type(ctx, "index", "index"); - if (!out->e_value.i_base.v_type) { - free(out); - return NULL; - } return out; } diff --git a/mie/dialect/index/index.c b/mie/dialect/index/index.c index 079a041..67e5d47 100644 --- a/mie/dialect/index/index.c +++ b/mie/dialect/index/index.c @@ -1,56 +1,44 @@ +#include #include #include #include #include #include #include -#include -struct index_type { - struct mie_type i_base; +struct index_dialect { + struct mie_dialect d_base; + struct mie_index_cache *ctx_indices; }; -static enum mie_status value_print( - const struct mie_value *value, struct mie_printer *out) +static enum mie_status init(struct mie_dialect *d) { - struct index_type *index_ty = (struct index_type *)value->v_type; - struct mie_index *index_val = (struct mie_index *)value; - b_stream_write_fmt( - out->p_stream, NULL, "%zu : %s", index_val->i_value, - index_ty->i_base.ty_def->ty_name); + struct index_dialect *dialect = (struct index_dialect *)d; + dialect->ctx_indices = mie_index_cache_create(); return MIE_SUCCESS; } -static void type_init( - const struct mie_type_definition *type_info, struct mie_type *type) +static enum mie_status cleanup(struct mie_dialect *d) { - type->ty_instance_size = sizeof(struct mie_index); -} - -static enum mie_status print(const struct mie_type *ty, struct mie_printer *out) -{ - b_stream_write_string( - out->p_stream, - (out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "index" : "index.index", - NULL); + struct index_dialect *dialect = (struct index_dialect *)d; + mie_index_cache_destroy(dialect->ctx_indices); return MIE_SUCCESS; } -static enum mie_status parse( - const struct mie_type_definition *def, struct mie_parser *parser, - struct mie_type **out) +struct mie_attribute *mie_ctx_get_index(struct mie_ctx *ctx, size_t val) { - return MIE_SUCCESS; + struct index_dialect *dialect + = (struct index_dialect *)mie_ctx_get_dialect(ctx, "index"); + if (!dialect) { + return NULL; + } + + return (struct mie_attribute *)mie_index_cache_get( + dialect->ctx_indices, ctx, val); } -MIE_TYPE_DEFINITION_BEGIN(mie_index_index, "index") - MIE_TYPE_DEFINITION_STRUCT(struct index_type); - MIE_TYPE_DEFINITION_INIT(type_init); - MIE_TYPE_DEFINITION_PRINT(print); - MIE_TYPE_DEFINITION_PARSE(parse); - MIE_TYPE_DEFINITION_VALUE_PRINT(value_print); -MIE_TYPE_DEFINITION_END() - -MIE_DIALECT_BEGIN(mie_index, "index") +MIE_DIALECT_BEGIN(mie_index, struct index_dialect, "index") + MIE_DIALECT_INIT(init); + MIE_DIALECT_CLEANUP(cleanup); MIE_DIALECT_ADD_TYPE(mie_index_index); MIE_DIALECT_END() diff --git a/mie/dialect/index/type/index.c b/mie/dialect/index/type/index.c new file mode 100644 index 0000000..f9e2ac8 --- /dev/null +++ b/mie/dialect/index/type/index.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include +#include +#include + +struct index_type { + struct mie_type i_base; +}; + +static void type_init( + const struct mie_type_definition *type_info, struct mie_type *type) +{ + type->ty_instance_size = sizeof(struct mie_index); +} + +static enum mie_status print(const struct mie_type *ty, struct mie_printer *out) +{ + b_stream_write_string( + out->p_stream, + (out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "index" : "!index.index", + NULL); + return MIE_SUCCESS; +} + +MIE_TYPE_DEFINITION_BEGIN(mie_index_index, "index") + MIE_TYPE_DEFINITION_STRUCT(struct index_type); + MIE_TYPE_DEFINITION_INIT(type_init); + MIE_TYPE_DEFINITION_PRINT(print); +MIE_TYPE_DEFINITION_END() diff --git a/mie/dialect/meta/meta.c b/mie/dialect/meta/meta.c index b3cbd62..44bfafb 100644 --- a/mie/dialect/meta/meta.c +++ b/mie/dialect/meta/meta.c @@ -1,6 +1,6 @@ #include #include -MIE_DIALECT_BEGIN(mie_meta, "meta") +MIE_DIALECT_BEGIN(mie_meta, struct mie_dialect, "meta") MIE_DIALECT_ADD_OP(mie_meta_source_filename); MIE_DIALECT_END() diff --git a/mie/dialect/meta/source-filename.c b/mie/dialect/meta/op/source-filename.c similarity index 100% rename from mie/dialect/meta/source-filename.c rename to mie/dialect/meta/op/source-filename.c diff --git a/mie/dialect/ptr/load.c b/mie/dialect/ptr/op/load.c similarity index 100% rename from mie/dialect/ptr/load.c rename to mie/dialect/ptr/op/load.c diff --git a/mie/dialect/ptr/store.c b/mie/dialect/ptr/op/store.c similarity index 100% rename from mie/dialect/ptr/store.c rename to mie/dialect/ptr/op/store.c diff --git a/mie/dialect/ptr/ptr.c b/mie/dialect/ptr/ptr.c index 107e1bf..816939d 100644 --- a/mie/dialect/ptr/ptr.c +++ b/mie/dialect/ptr/ptr.c @@ -2,29 +2,7 @@ #include #include -struct ptr_type { - struct mie_type_definition ptr_base; -}; - -static enum mie_status print(const struct mie_type *ty, struct mie_printer *out) -{ - return MIE_SUCCESS; -} - -static enum mie_status parse( - const struct mie_type_definition *def, struct mie_parser *parser, - struct mie_type **out) -{ - return MIE_SUCCESS; -} - -MIE_TYPE_DEFINITION_BEGIN(mie_ptr_ptr, "ptr") - MIE_TYPE_DEFINITION_STRUCT(struct ptr_type); - MIE_TYPE_DEFINITION_PRINT(print); - MIE_TYPE_DEFINITION_PARSE(parse); -MIE_TYPE_DEFINITION_END() - -MIE_DIALECT_BEGIN(mie_ptr, "ptr") +MIE_DIALECT_BEGIN(mie_ptr, struct mie_dialect, "ptr") MIE_DIALECT_ADD_OP(mie_ptr_load); MIE_DIALECT_ADD_OP(mie_ptr_store); MIE_DIALECT_ADD_TYPE(mie_ptr_ptr); diff --git a/mie/dialect/ptr/type/ptr.c b/mie/dialect/ptr/type/ptr.c new file mode 100644 index 0000000..a8f8928 --- /dev/null +++ b/mie/dialect/ptr/type/ptr.c @@ -0,0 +1,17 @@ +#include +#include +#include + +struct ptr_type { + struct mie_type_definition ptr_base; +}; + +static enum mie_status print(const struct mie_type *ty, struct mie_printer *out) +{ + return MIE_SUCCESS; +} + +MIE_TYPE_DEFINITION_BEGIN(mie_ptr_ptr, "ptr") + MIE_TYPE_DEFINITION_STRUCT(struct ptr_type); + MIE_TYPE_DEFINITION_PRINT(print); +MIE_TYPE_DEFINITION_END() diff --git a/mie/dialect/scf/for.c b/mie/dialect/scf/op/for.c similarity index 100% rename from mie/dialect/scf/for.c rename to mie/dialect/scf/op/for.c diff --git a/mie/dialect/scf/if.c b/mie/dialect/scf/op/if.c similarity index 100% rename from mie/dialect/scf/if.c rename to mie/dialect/scf/op/if.c diff --git a/mie/dialect/scf/yield.c b/mie/dialect/scf/op/yield.c similarity index 100% rename from mie/dialect/scf/yield.c rename to mie/dialect/scf/op/yield.c diff --git a/mie/dialect/scf/scf.c b/mie/dialect/scf/scf.c index 0bc2562..898327d 100644 --- a/mie/dialect/scf/scf.c +++ b/mie/dialect/scf/scf.c @@ -1,7 +1,7 @@ #include #include -MIE_DIALECT_BEGIN(mie_scf, "scf") +MIE_DIALECT_BEGIN(mie_scf, struct mie_dialect, "scf") MIE_DIALECT_ADD_OP(mie_scf_if); MIE_DIALECT_ADD_OP(mie_scf_for); MIE_DIALECT_ADD_OP(mie_scf_yield); diff --git a/mie/dialect/select/graph-only.c b/mie/dialect/select/attribute/graph-only.c similarity index 100% rename from mie/dialect/select/graph-only.c rename to mie/dialect/select/attribute/graph-only.c diff --git a/mie/dialect/select/graph-op.c b/mie/dialect/select/attribute/graph-op.c similarity index 100% rename from mie/dialect/select/graph-op.c rename to mie/dialect/select/attribute/graph-op.c diff --git a/mie/dialect/select/graph-scope.c b/mie/dialect/select/attribute/graph-scope.c similarity index 100% rename from mie/dialect/select/graph-scope.c rename to mie/dialect/select/attribute/graph-scope.c diff --git a/mie/dialect/select/graph.c b/mie/dialect/select/op/graph.c similarity index 100% rename from mie/dialect/select/graph.c rename to mie/dialect/select/op/graph.c diff --git a/mie/dialect/select/select.c b/mie/dialect/select/select.c index 90a4266..3174857 100644 --- a/mie/dialect/select/select.c +++ b/mie/dialect/select/select.c @@ -1,7 +1,7 @@ #include #include -MIE_DIALECT_BEGIN(mie_select, "select") +MIE_DIALECT_BEGIN(mie_select, struct mie_dialect, "select") MIE_DIALECT_ADD_TRAIT(mie_select_graph_only); MIE_DIALECT_ADD_TRAIT(mie_select_graph_op); MIE_DIALECT_ADD_TRAIT(mie_select_graph_scope); diff --git a/mie/include/mie/attribute/attribute-definition.h b/mie/include/mie/attribute/attribute-definition.h new file mode 100644 index 0000000..acaaa6b --- /dev/null +++ b/mie/include/mie/attribute/attribute-definition.h @@ -0,0 +1,29 @@ +#ifndef MIE_ATTRIBUTE_ATTRIBUTE_DEFINITION_H_ +#define MIE_ATTRIBUTE_ATTRIBUTE_DEFINITION_H_ + +#include + +struct mie_dialect; +struct mie_attribute; +struct mie_parser; +struct mie_printer; + +struct mie_attribute_definition { + mie_id a_id; + struct mie_dialect *a_parent; + char *a_name; + + size_t a_data_size; + + void (*a_init)(struct mie_attribute *); + void (*a_cleanup)(struct mie_attribute *); + enum mie_status (*a_print)( + const struct mie_attribute *, struct mie_printer *); + enum mie_status (*a_parse)( + struct mie_parser *, const struct mie_attribute **); +}; + +MIE_API struct mie_attribute_definition *mie_attribute_definition_create( + struct mie_dialect *parent, const char *name); + +#endif diff --git a/mie/include/mie/attribute/attribute-map.h b/mie/include/mie/attribute/attribute-map.h new file mode 100644 index 0000000..aba6ac0 --- /dev/null +++ b/mie/include/mie/attribute/attribute-map.h @@ -0,0 +1,44 @@ +#ifndef MIE_ATTRIBUTE_ATTRIBUTE_MAP_H_ +#define MIE_ATTRIBUTE_ATTRIBUTE_MAP_H_ + +#include +#include +#include + +struct b_queue_entry; + +struct mie_attribute_map { + b_btree m_entries; +}; + +enum mie_attribute_map_flags { + MIE_ATTRMAP_F_REPLACE = 0x01u, +}; + +struct mie_attribute_map_iterator { + const char *it_name; + const struct mie_attribute *it_value; + b_btree_node *_n; + struct b_queue_entry *_e; +}; + +MIE_API void mie_attribute_map_init(struct mie_attribute_map *map); +MIE_API void mie_attribute_map_cleanup(struct mie_attribute_map *map); + +static inline bool mie_attribute_map_empty(const struct mie_attribute_map *map) +{ + return b_btree_empty(&map->m_entries); +} + +MIE_API const struct mie_attribute *mie_attribute_map_get( + const struct mie_attribute_map *map, const char *name); +MIE_API enum mie_status mie_attribute_map_put( + struct mie_attribute_map *map, const char *name, + const struct mie_attribute *value, enum mie_attribute_map_flags flags); + +MIE_API enum mie_status mie_attribute_map_iterator_begin( + struct mie_attribute_map_iterator *it, const struct mie_attribute_map *map); +MIE_API enum mie_status mie_attribute_map_iterator_move_next( + struct mie_attribute_map_iterator *it); + +#endif diff --git a/mie/include/mie/attribute/attribute.h b/mie/include/mie/attribute/attribute.h new file mode 100644 index 0000000..afa8613 --- /dev/null +++ b/mie/include/mie/attribute/attribute.h @@ -0,0 +1,10 @@ +#ifndef MIE_ATTRIBUTE_ATTRIBUTE_H_ +#define MIE_ATTRIBUTE_ATTRIBUTE_H_ + +struct mie_attribute_definition; + +struct mie_attribute { + const struct mie_attribute_definition *a_def; +}; + +#endif diff --git a/mie/include/mie/ctx.h b/mie/include/mie/ctx.h index 6c55404..f92ee06 100644 --- a/mie/include/mie/ctx.h +++ b/mie/include/mie/ctx.h @@ -25,11 +25,8 @@ struct mie_ctx { struct mie_id_map ctx_types; /* map of struct mie_trait */ struct mie_id_map ctx_traits; - - struct mie_int_cache *ctx_ints; - struct mie_float_cache *ctx_floats; - struct mie_index_cache *ctx_indices; - struct mie_string_cache *ctx_strings; + /* map of struct mie_attribute */ + struct mie_id_map ctx_attributes; }; MIE_API struct mie_ctx *mie_ctx_create(void); @@ -44,6 +41,9 @@ MIE_API struct mie_type_definition *mie_ctx_get_type_definition( MIE_API const struct mie_trait_definition *mie_ctx_get_trait_definition( const struct mie_ctx *ctx, const char *dialect_name, const char *trait_name); +MIE_API const struct mie_attribute_definition *mie_ctx_get_attribute_definition( + const struct mie_ctx *ctx, const char *dialect_name, + const char *attrib_name); MIE_API struct mie_type *mie_ctx_get_type( struct mie_ctx *ctx, const char *dialect_name, const char *type_name); MIE_API const struct mie_trait *mie_ctx_get_trait( @@ -55,11 +55,5 @@ MIE_API struct mie_type *mie_ctx_get_function_type( const struct mie_type **out, size_t nr_out); MIE_API struct mie_value *mie_ctx_get_null(struct mie_ctx *ctx); -MIE_API struct mie_value *mie_ctx_get_int( - struct mie_ctx *ctx, long long val, size_t nr_bits); -MIE_API struct mie_value *mie_ctx_get_float( - struct mie_ctx *ctx, double val, size_t nr_bits); -MIE_API struct mie_value *mie_ctx_get_string(struct mie_ctx *ctx, const char *s); -MIE_API struct mie_value *mie_ctx_get_index(struct mie_ctx *ctx, size_t val); #endif diff --git a/mie/include/mie/dialect/arith.h b/mie/include/mie/dialect/arith.h index f70a4b4..8532927 100644 --- a/mie/include/mie/dialect/arith.h +++ b/mie/include/mie/dialect/arith.h @@ -1,8 +1,8 @@ #ifndef MIE_DIALECT_ARITH_H_ #define MIE_DIALECT_ARITH_H_ +#include #include -#include #include #include @@ -15,7 +15,9 @@ enum mie_float_width { }; struct mie_int { - struct mie_value i_base; + struct mie_attribute i_base; + const struct mie_type *i_type; + union { int64_t v_small; @@ -27,7 +29,8 @@ struct mie_int { }; struct mie_float { - struct mie_value f_base; + struct mie_attribute f_base; + const struct mie_type *f_type; union { float v_32; @@ -59,4 +62,9 @@ MIE_API struct mie_float *mie_float_cache_get( struct mie_float_cache *cache, struct mie_ctx *ctx, double value, size_t bit_width); +MIE_API struct mie_attribute *mie_ctx_get_int( + struct mie_ctx *ctx, long long val, size_t nr_bits); +MIE_API struct mie_attribute *mie_ctx_get_float( + struct mie_ctx *ctx, double val, size_t nr_bits); + #endif diff --git a/mie/include/mie/dialect/builtin.h b/mie/include/mie/dialect/builtin.h index 957ca39..bf7c504 100644 --- a/mie/include/mie/dialect/builtin.h +++ b/mie/include/mie/dialect/builtin.h @@ -2,8 +2,8 @@ #define MIE_DIALECT_BUILTIN_H_ #include +#include #include -#include struct mie_dialect; @@ -12,7 +12,7 @@ struct mie_int_type; struct mie_float_type; struct mie_string { - struct mie_value str_base; + struct mie_attribute str_base; char *str_val; size_t str_len; }; @@ -26,4 +26,7 @@ MIE_API void mie_string_cache_destroy(struct mie_string_cache *cache); MIE_API struct mie_string *mie_string_cache_get( struct mie_string_cache *cache, struct mie_ctx *ctx, const char *val); +MIE_API struct mie_attribute *mie_ctx_get_string( + struct mie_ctx *ctx, const char *s); + #endif diff --git a/mie/include/mie/dialect/dialect.h b/mie/include/mie/dialect/dialect.h index e2c1387..3838351 100644 --- a/mie/include/mie/dialect/dialect.h +++ b/mie/include/mie/dialect/dialect.h @@ -23,10 +23,14 @@ struct mie_dialect { struct mie_id_map d_types; /* map of struct mie_trait_definition */ struct mie_id_map d_traits; + /* map of struct mie_attribute_definition */ + struct mie_id_map d_attributes; + + enum mie_status (*d_cleanup)(struct mie_dialect *); }; MIE_API struct mie_dialect *mie_dialect_create( - struct mie_ctx *ctx, const char *name); + struct mie_ctx *ctx, const char *name, size_t size); MIE_API const struct mie_op_definition *mie_dialect_get_op( const struct mie_dialect *dialect, const char *name); @@ -34,5 +38,7 @@ MIE_API const struct mie_type_definition *mie_dialect_get_type( const struct mie_dialect *dialect, const char *name); MIE_API const struct mie_trait_definition *mie_dialect_get_trait( const struct mie_dialect *dialect, const char *name); +MIE_API const struct mie_attribute_definition *mie_dialect_get_attribute( + const struct mie_dialect *dialect, const char *name); #endif diff --git a/mie/include/mie/dialect/index.h b/mie/include/mie/dialect/index.h index 3a73cbb..9aabcfa 100644 --- a/mie/include/mie/dialect/index.h +++ b/mie/include/mie/dialect/index.h @@ -1,8 +1,8 @@ #ifndef MIE_DIALECT_INDEX_H_ #define MIE_DIALECT_INDEX_H_ +#include #include -#include #include #include @@ -10,7 +10,7 @@ struct mie_ctx; struct mie_dialect; struct mie_index { - struct mie_value i_base; + struct mie_attribute i_base; size_t i_value; }; @@ -23,4 +23,6 @@ MIE_API void mie_index_cache_destroy(struct mie_index_cache *cache); MIE_API struct mie_index *mie_index_cache_get( struct mie_index_cache *cache, struct mie_ctx *ctx, size_t value); +MIE_API struct mie_attribute *mie_ctx_get_index(struct mie_ctx *ctx, size_t val); + #endif diff --git a/mie/include/mie/dialect/memref.h b/mie/include/mie/dialect/memref.h new file mode 100644 index 0000000..df27bed --- /dev/null +++ b/mie/include/mie/dialect/memref.h @@ -0,0 +1,13 @@ +#ifndef MIE_DIALECT_MEMREF_H_ +#define MIE_DIALECT_MEMREF_H_ + +#include +#include +#include + +struct mie_ctx; +struct mie_dialect; + +MIE_API struct mie_dialect *mie_memref_dialect_create(struct mie_ctx *ctx); + +#endif diff --git a/mie/include/mie/ir/op.h b/mie/include/mie/ir/op.h index 5c48ccf..103e4ac 100644 --- a/mie/include/mie/ir/op.h +++ b/mie/include/mie/ir/op.h @@ -3,6 +3,7 @@ #include "mie/vector.h" +#include #include #include #include @@ -23,11 +24,6 @@ enum mie_op_flags { MIE_OP_F_SUCCESSOR_RESOLVED = 0x04u, }; -struct mie_op_attribute { - char *attrib_name; - struct mie_value *attrib_value; -}; - struct mie_op_arg { enum mie_op_flags arg_flags; struct mie_file_span arg_span; @@ -65,7 +61,7 @@ struct mie_op { MIE_VECTOR_DECLARE(struct mie_region, op_regions); MIE_VECTOR_DECLARE(struct mie_op_successor, op_successors); - MIE_VECTOR_DECLARE(struct mie_op_attribute, op_attrib); + struct mie_attribute_map op_attrib; MIE_VECTOR_DECLARE(struct mie_op_arg, op_args); MIE_VECTOR_DECLARE(struct mie_register *, op_result); }; diff --git a/mie/include/mie/macros.h b/mie/include/mie/macros.h index f4202d5..a15d5a2 100644 --- a/mie/include/mie/macros.h +++ b/mie/include/mie/macros.h @@ -1,16 +1,18 @@ #ifndef MIE_MACROS_H_ #define MIE_MACROS_H_ -#define __MIE_DIALECT_BEGIN(func_prefix, dialect_name) \ - struct mie_dialect *func_prefix##_dialect_create(struct mie_ctx *ctx) \ - { \ - struct mie_dialect *self = mie_dialect_create(ctx, dialect_name); \ - if (!self) { \ - return NULL; \ - } \ - struct mie_op_definition *op = NULL; \ - struct mie_type_definition *type = NULL; \ - struct mie_trait_definition *trait = 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; #define __MIE_DIALECT_END() \ return self; \ @@ -60,6 +62,22 @@ return trait; \ } +#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_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 *); \ @@ -73,11 +91,20 @@ struct mie_dialect *, struct mie_ctx *); \ trait = trait_id##_trait_create(self, ctx) -#define MIE_DIALECT_BEGIN(c_sym, name) __MIE_DIALECT_BEGIN(c_sym, name) +#define __MIE_DIALECT_ADD_ATTRIBUTE(attribute_id) \ + extern struct mie_attribute_definition *attribute_id##_attribute_create( \ + struct mie_dialect *, struct mie_ctx *); \ + attribute = attribute_id##_attribute_create(self, ctx) + +#define MIE_DIALECT_BEGIN(c_sym, c_struct, name) \ + __MIE_DIALECT_BEGIN(c_sym, c_struct, name) #define MIE_DIALECT_END() __MIE_DIALECT_END() +#define MIE_DIALECT_INIT(func) __MIE_DIALECT_INIT(func) +#define MIE_DIALECT_CLEANUP(func) __MIE_DIALECT_CLEANUP(func) #define MIE_DIALECT_ADD_OP(c_sym) __MIE_DIALECT_ADD_OP(c_sym) #define MIE_DIALECT_ADD_TYPE(c_sym) __MIE_DIALECT_ADD_TYPE(c_sym) #define MIE_DIALECT_ADD_TRAIT(c_sym) __MIE_DIALECT_ADD_TRAIT(c_sym) +#define MIE_DIALECT_ADD_ATTRIBUTE(c_sym) __MIE_DIALECT_ADD_ATTRIBUTE(c_sym) #define MIE_OP_DEFINITION_BEGIN(c_sym, op) __MIE_OP_DEFINITION_BEGIN(c_sym, op) #define MIE_OP_DEFINITION_END() __MIE_OP_DEFINITION_END() @@ -89,16 +116,15 @@ #define MIE_TYPE_DEFINITION_BEGIN(c_sym, type) \ __MIE_TYPE_DEFINITION_BEGIN(c_sym, type) -#define MIE_TYPE_DEFINITION_END() __MIE_TYPE_DEFINITION_END() -#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_VALUE_PRINT(func) type->ty_value_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_END() __MIE_TYPE_DEFINITION_END() +#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); @@ -113,4 +139,14 @@ #define MIE_TRAIT_DEFINITION_CLEANUP(func) trait->tr_cleanup = (func) #define MIE_TRAIT_DEFINITION_VALIDATE(func) trait->tr_validate = (func) +#define MIE_ATTRIBUTE_DEFINITION_BEGIN(c_sym, attribute) \ + __MIE_ATTRIBUTE_DEFINITION_BEGIN(c_sym, attribute) +#define MIE_ATTRIBUTE_DEFINITION_END() __MIE_ATTRIBUTE_DEFINITION_END() +#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) + #endif diff --git a/mie/include/mie/parse/parser.h b/mie/include/mie/parse/parser.h index 2e3d6c1..64c06a8 100644 --- a/mie/include/mie/parse/parser.h +++ b/mie/include/mie/parse/parser.h @@ -22,12 +22,18 @@ struct mie_op_arg; struct mie_op_attribute; struct mie_op_successor; struct mie_register; -struct mie_value; +struct mie_attribute_map; +struct mie_attribute; MIE_API struct mie_parser *mie_parser_create( struct mie_ctx *ctx, struct mie_lex *lex); MIE_API void mie_parser_destroy(struct mie_parser *ctx); + +MIE_API struct mie_ctx *mie_parser_get_mie_ctx(struct mie_parser *ctx); +MIE_API struct mie_lex *mie_parser_get_lexer(struct mie_parser *ctx); MIE_API enum mie_status mie_parser_get_status(const struct mie_parser *ctx); +MIE_API void mie_parser_set_status(struct mie_parser *ctx, enum mie_status status); +MIE_API b_string *mie_parser_get_tempstr(struct mie_parser *ctx); MIE_API struct mie_token *mie_parser_peek(struct mie_parser *ctx); MIE_API enum mie_token_type mie_parser_peek_type(struct mie_parser *ctx); @@ -57,6 +63,8 @@ MIE_API bool mie_parser_parse_mregname( struct mie_parser *ctx, b_string *out, struct mie_file_span *loc); MIE_API bool mie_parser_parse_blockname( struct mie_parser *ctx, b_string *out, struct mie_file_span *loc); +MIE_API bool mie_parser_parse_attribname( + struct mie_parser *ctx, b_string *out, struct mie_file_span *loc); MIE_API bool mie_parser_parse_typename( struct mie_parser *ctx, b_string *out, struct mie_file_span *loc); MIE_API bool mie_parser_parse_symname( @@ -107,11 +115,6 @@ MIE_API bool mie_parser_parse_block( struct mie_parser *ctx, struct mie_name_map *names, struct mie_block *block); -MIE_API bool mie_parser_parse_attribute( - struct mie_parser *ctx, struct mie_op_attribute *attrib); -MIE_API bool mie_parser_parse_attribute_list( - struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_attribute, out)); - MIE_API bool mie_parser_parse_successor( struct mie_parser *ctx, struct mie_op_successor *successor); MIE_API bool mie_parser_parse_successor_list( @@ -120,6 +123,10 @@ MIE_API bool mie_parser_parse_successor_list( MIE_API bool mie_parser_parse_module(struct mie_parser *ctx, struct mie_module *mod); MIE_API bool mie_parser_parse_op( struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest); -MIE_API bool mie_parser_parse_value(struct mie_parser *ctx, struct mie_value **dest); + +MIE_API bool mie_parser_parse_attribute( + struct mie_parser *ctx, const struct mie_attribute **dest); +MIE_API bool mie_parser_parse_attribute_map( + struct mie_parser *ctx, struct mie_attribute_map *out); #endif diff --git a/mie/include/mie/parse/token.h b/mie/include/mie/parse/token.h index 5fec578..f121cc6 100644 --- a/mie/include/mie/parse/token.h +++ b/mie/include/mie/parse/token.h @@ -35,8 +35,10 @@ enum mie_token_type { MIE_TOK_MREGNAME = 0x1000u, /* word or name, prefixed with a ^ caret */ MIE_TOK_BLOCKNAME = 0x2000u, - /* word or name, prefixed with a # hash */ + /* word or name, prefixed with a ! hash */ MIE_TOK_TYPENAME = 0x4000u, + /* word or name, prefixed with a # hash */ + MIE_TOK_ATTRIBNAME = 0x8000u, }; enum mie_token_value_type { @@ -60,6 +62,7 @@ enum mie_token_symbol { MIE_SYM_CARET, MIE_SYM_HASH, MIE_SYM_TILDE, + MIE_SYM_BANG, MIE_SYM_ATSIGN, MIE_SYM_LEFT_BRACE, MIE_SYM_RIGHT_BRACE, diff --git a/mie/include/mie/print/printer.h b/mie/include/mie/print/printer.h index 72be348..f585fad 100644 --- a/mie/include/mie/print/printer.h +++ b/mie/include/mie/print/printer.h @@ -11,7 +11,7 @@ struct mie_op; struct mie_region; struct mie_block; struct mie_type; -struct mie_value; +struct mie_attribute; struct mie_register; enum mie_print_flags { @@ -39,8 +39,8 @@ MIE_API void mie_printer_print_block( struct mie_printer *printer, const struct mie_block *block); MIE_API void mie_printer_print_type( struct mie_printer *printer, const struct mie_type *type); -MIE_API void mie_printer_print_value( - struct mie_printer *printer, const struct mie_value *value); +MIE_API void mie_printer_print_attribute( + struct mie_printer *printer, const struct mie_attribute *attrib); MIE_API void mie_printer_print_register( struct mie_printer *printer, const struct mie_register *reg); diff --git a/mie/include/mie/status.h b/mie/include/mie/status.h index f937b74..2811d74 100644 --- a/mie/include/mie/status.h +++ b/mie/include/mie/status.h @@ -12,6 +12,7 @@ enum mie_status { MIE_ERR_EOF, MIE_ERR_BAD_SYNTAX, MIE_ERR_BAD_FORMAT, + MIE_ERR_BAD_STATE, MIE_ERR_NOT_SUPPORTED, MIE_ERR_INVALID_VALUE, MIE_ERR_INVALID_ARGUMENT, diff --git a/mie/include/mie/type/type-definition.h b/mie/include/mie/type/type-definition.h index 611d71f..0caf34b 100644 --- a/mie/include/mie/type/type-definition.h +++ b/mie/include/mie/type/type-definition.h @@ -21,11 +21,7 @@ struct mie_type_definition { void (*ty_cleanup)(const struct mie_type_definition *, struct mie_type *); void (*ty_instance_cleanup)(const struct mie_type *, struct mie_value *); enum mie_status (*ty_print)(const struct mie_type *, struct mie_printer *); - enum mie_status (*ty_value_print)( - const struct mie_value *, struct mie_printer *); - enum mie_status (*ty_parse)( - const struct mie_type_definition *, struct mie_parser *, - struct mie_type **); + enum mie_status (*ty_parse)(struct mie_parser *, const struct mie_type **); void (*ty_build_id)(const struct mie_type *, struct mie_id_builder *); }; diff --git a/mie/include/mie/value.h b/mie/include/mie/value.h deleted file mode 100644 index f5aab2d..0000000 --- a/mie/include/mie/value.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef MIE_VALUE_VALUE_H_ -#define MIE_VALUE_VALUE_H_ - -#include - -struct mie_type; - -struct mie_value { - struct mie_type *v_type; -}; - -#endif diff --git a/mie/parse/lex.c b/mie/parse/lex.c index 734d3bc..2ce84df 100644 --- a/mie/parse/lex.c +++ b/mie/parse/lex.c @@ -35,6 +35,7 @@ static struct lex_token_def symbols[] = { LEX_TOKEN_DEF(MIE_SYM_CARET, "^"), LEX_TOKEN_DEF(MIE_SYM_HASH, "#"), LEX_TOKEN_DEF(MIE_SYM_ATSIGN, "@"), + LEX_TOKEN_DEF(MIE_SYM_BANG, "!"), LEX_TOKEN_DEF(MIE_SYM_TILDE, "~"), LEX_TOKEN_DEF(MIE_SYM_LEFT_BRACE, "{"), LEX_TOKEN_DEF(MIE_SYM_RIGHT_BRACE, "}"), @@ -705,6 +706,8 @@ static enum mie_status read_symbol(struct mie_lex *lex) case MIE_SYM_TILDE: return read_ident(lex, MIE_TOK_OPNAME); case MIE_SYM_HASH: + return read_ident(lex, MIE_TOK_ATTRIBNAME); + case MIE_SYM_BANG: return read_ident(lex, MIE_TOK_TYPENAME); case MIE_SYM_ATSIGN: return read_ident(lex, MIE_TOK_SYMNAME); diff --git a/mie/parse/parser.c b/mie/parse/parser.c index 53214bc..4032871 100644 --- a/mie/parse/parser.c +++ b/mie/parse/parser.c @@ -1,6 +1,10 @@ +#include +#include #include #include +#include #include +#include #include #include #include @@ -26,6 +30,47 @@ static b_string *get_temp_string(struct mie_parser *parser) return parser->s_tmp; } +#define GET_SOMETHING_BY_FULL_NAME(thing) \ + static const struct mie_##thing##_definition *get_##thing##_by_full_name( \ + struct mie_parser *ctx, b_string *name) \ + { \ + b_string *dialect = b_string_create(); \ + b_string *item = b_string_create(); \ + const char *delim[] = {"."}; \ + size_t i = 0; \ + b_iterator *it = b_string_tokenise( \ + name, delim, 1, B_STRING_TOK_F_NORMAL); \ + while (b_iterator_is_valid(it)) { \ + const char *tok = b_iterator_get_cvalue(it).v_cptr; \ + switch (i) { \ + case 0: \ + b_string_append_cstr(dialect, tok); \ + break; \ + case 1: \ + b_string_append_cstr(item, tok); \ + break; \ + default: \ + b_string_append_c(item, '.'); \ + b_string_append_cstr(item, tok); \ + break; \ + } \ + b_iterator_move_next(it); \ + i++; \ + } \ + b_iterator_unref(it); \ + const struct mie_##thing##_definition *def \ + = mie_ctx_get_##thing##_definition( \ + ctx->p_ctx, b_string_ptr(dialect), \ + b_string_ptr(item)); \ + b_string_unref(dialect); \ + b_string_unref(item); \ + return def; \ + } + +GET_SOMETHING_BY_FULL_NAME(trait); +GET_SOMETHING_BY_FULL_NAME(type); +GET_SOMETHING_BY_FULL_NAME(attribute); + struct mie_parser *mie_parser_create(struct mie_ctx *ctx, struct mie_lex *lex) { struct mie_parser *out = malloc(sizeof *out); @@ -57,11 +102,31 @@ void mie_parser_destroy(struct mie_parser *ctx) free(ctx); } +struct mie_ctx *mie_parser_get_mie_ctx(struct mie_parser *ctx) +{ + return ctx->p_ctx; +} + +struct mie_lex *mie_parser_get_lexer(struct mie_parser *ctx) +{ + return ctx->p_lex; +} + enum mie_status mie_parser_get_status(const struct mie_parser *ctx) { return ctx->p_status; } +void mie_parser_set_status(struct mie_parser *ctx, enum mie_status status) +{ + ctx->p_status = status; +} + +b_string *mie_parser_get_tempstr(struct mie_parser *ctx) +{ + return get_temp_string(ctx); +} + struct mie_token *mie_parser_peek(struct mie_parser *ctx) { return mie_lex_peek(ctx->p_lex); @@ -178,6 +243,7 @@ TOKEN_PARSER(opname, MIE_TOK_OPNAME); TOKEN_PARSER(vregname, MIE_TOK_VREGNAME); TOKEN_PARSER(mregname, MIE_TOK_MREGNAME); TOKEN_PARSER(blockname, MIE_TOK_BLOCKNAME); +TOKEN_PARSER(attribname, MIE_TOK_ATTRIBNAME); TOKEN_PARSER(typename, MIE_TOK_TYPENAME); TOKEN_PARSER(symname, MIE_TOK_SYMNAME); TOKEN_PARSER(string, MIE_TOK_STRING); @@ -253,6 +319,8 @@ static bool parse_builtin_type_name( return false; } + enum mie_status status = MIE_SUCCESS; + switch (base_type) { case INT: type = mie_arith_int_get_type(ctx->p_ctx, width); @@ -261,12 +329,21 @@ static bool parse_builtin_type_name( type = mie_arith_float_get_type(ctx->p_ctx, width); break; default: - type = mie_ctx_get_type( - ctx->p_ctx, type_info->ty_parent->d_name, - type_info->ty_name); + if (type_info->ty_parse) { + status = type_info->ty_parse(ctx, &type); + } else { + type = mie_ctx_get_type( + ctx->p_ctx, type_info->ty_parent->d_name, + type_info->ty_name); + } + break; } + if (!type || status != MIE_SUCCESS) { + type = NULL; + } + *out = type; return type != NULL; } @@ -895,69 +972,6 @@ bool mie_parser_parse_block( return true; } -bool mie_parser_parse_attribute( - struct mie_parser *ctx, struct mie_op_attribute *attrib) -{ - b_string *str = get_temp_string(ctx); - struct mie_file_span span; - if (!mie_parser_parse_word(ctx, str, &span)) { - return false; - } - - attrib->attrib_name = b_string_steal(str); - - if (!mie_parser_parse_symbol(ctx, MIE_SYM_EQUAL)) { - return false; - } - - struct mie_value *value = NULL; - if (!mie_parser_parse_value(ctx, &value)) { - return false; - } - - attrib->attrib_value = value; - - return true; -} - -bool mie_parser_parse_attribute_list( - struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_attribute, out)) -{ - bool ok = false; - struct mie_op_attribute *attrib = NULL; - - attrib = mie_vector_ref_emplace_back(out); - if (!attrib) { - return false; - } - - if (!mie_parser_parse_attribute(ctx, attrib)) { - return false; - } - - while (1) { - const struct mie_token *tok = mie_parser_peek(ctx); - - if (!MIE_TOKEN_IS_SYMBOL(tok, MIE_SYM_COMMA)) { - break; - } - - mie_parser_advance(ctx); - mie_parser_parse_linefeed(ctx); - - attrib = mie_vector_ref_emplace_back(out); - if (!attrib) { - return false; - } - - if (!mie_parser_parse_attribute(ctx, attrib)) { - return false; - } - } - - return true; -} - bool mie_parser_parse_successor(struct mie_parser *ctx, struct mie_op_successor *out) { memset(out, 0x0, sizeof *out); @@ -1117,8 +1131,7 @@ static bool parse_generic_op( } if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACE)) { - if (!mie_parser_parse_attribute_list( - ctx, MIE_VECTOR_REF(dest->op_attrib))) { + if (!mie_parser_parse_attribute_map(ctx, &dest->op_attrib)) { return false; } @@ -1168,6 +1181,7 @@ bool mie_parser_parse_op( struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest) { memset(dest, 0x0, sizeof *dest); + mie_attribute_map_init(&dest->op_attrib); if (mie_parser_check_eof(ctx)) { return false; @@ -1199,100 +1213,138 @@ bool mie_parser_parse_op( } } -static bool parse_string(struct mie_parser *ctx, struct mie_value **dest) -{ - b_string *str = get_temp_string(ctx); - struct mie_file_span span; - if (!mie_parser_parse_string(ctx, str, &span)) { - return false; - } - - struct mie_value *v = mie_ctx_get_string(ctx->p_ctx, b_string_ptr(str)); - - if (!v) { - return false; - } - - *dest = v; - return true; -} - -static bool parse_int(struct mie_parser *ctx, struct mie_value **dest) -{ - long long value = 0; - struct mie_file_span span; - - if (!mie_parser_parse_int(ctx, &value, &span)) { - return false; - } - - if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) { - return false; - } - - const struct mie_type *type = NULL; - if (!mie_parser_parse_type(ctx, &type)) { - return false; - } - - size_t width = mie_arith_int_type_get_width(type); - if (width == (size_t)-1) { - return false; - } - - struct mie_value *v = mie_ctx_get_int(ctx->p_ctx, value, width); - if (!v) { - return false; - } - - *dest = v; - return true; -} - -static bool parse_float(struct mie_parser *ctx, struct mie_value **dest) -{ - double value = 0; - struct mie_file_span span; - - if (!mie_parser_parse_float(ctx, &value, &span)) { - return false; - } - - if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) { - return false; - } - - const struct mie_type *type = NULL; - if (!mie_parser_parse_type(ctx, &type)) { - return false; - } - - size_t width = mie_arith_float_type_get_width(type); - if (width == (size_t)-1) { - return false; - } - - struct mie_value *v = mie_ctx_get_float(ctx->p_ctx, value, width); - if (!v) { - return false; - } - - *dest = v; - return true; -} - -bool mie_parser_parse_value(struct mie_parser *ctx, struct mie_value **dest) +bool mie_parser_parse_attribute( + struct mie_parser *ctx, const struct mie_attribute **dest) { enum mie_token_type type = mie_parser_peek_type(ctx); + const struct mie_attribute_definition *attribute = NULL; + b_string *str = get_temp_string(ctx); + struct mie_file_span span; + bool need_angle_delim = false; switch (type) { case MIE_TOK_STRING: - return parse_string(ctx, dest); + attribute = mie_ctx_get_attribute_definition( + ctx->p_ctx, "builtin", "string"); + break; case MIE_TOK_INT: - return parse_int(ctx, dest); + attribute = mie_ctx_get_attribute_definition( + ctx->p_ctx, "arith", "int"); + break; case MIE_TOK_FLOAT: - return parse_float(ctx, dest); + attribute = mie_ctx_get_attribute_definition( + ctx->p_ctx, "arith", "float"); + break; + case MIE_TOK_SYMBOL: + switch (mie_parser_peek_symbol(ctx)) { + case MIE_SYM_LEFT_BRACKET: + attribute = mie_ctx_get_attribute_definition( + ctx->p_ctx, "builtin", "array"); + break; + case MIE_SYM_LEFT_BRACE: + attribute = mie_ctx_get_attribute_definition( + ctx->p_ctx, "builtin", "dict"); + break; + default: + break; + } + break; + case MIE_TOK_ATTRIBNAME: + if (!mie_parser_parse_attribname(ctx, str, &span)) { + return false; + } + + attribute = get_attribute_by_full_name(ctx, str); + need_angle_delim = true; + break; + case MIE_TOK_TYPENAME: + case MIE_TOK_WORD: + attribute = mie_ctx_get_attribute_definition( + ctx->p_ctx, "builtin", "type"); + break; default: + break; + } + + if (!attribute || !attribute->a_parse) { return false; } + + if (need_angle_delim && !mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_ANGLE)) { + return false; + } + + if (!attribute->a_parse(ctx, dest)) { + return false; + } + + if (need_angle_delim && !mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_ANGLE)) { + return false; + } + + return true; +} + +static bool parse_attribute_map_entry( + struct mie_parser *ctx, char **out_name, + const struct mie_attribute **out_value) +{ + b_string *str = get_temp_string(ctx); + struct mie_file_span span; + if (!mie_parser_parse_word(ctx, str, &span)) { + return false; + } + + char *name = b_string_steal(str); + + if (!mie_parser_parse_symbol(ctx, MIE_SYM_EQUAL)) { + free(name); + return false; + } + + const struct mie_attribute *value = NULL; + if (!mie_parser_parse_attribute(ctx, &value)) { + free(name); + return false; + } + + *out_name = name; + *out_value = value; + + return true; +} + +bool mie_parser_parse_attribute_map( + struct mie_parser *ctx, struct mie_attribute_map *out) +{ + char *name = NULL; + const struct mie_attribute *value = NULL; + + bool ok = false; + + if (mie_parser_peek_type(ctx) != MIE_TOK_WORD) { + return false; + } + + if (!parse_attribute_map_entry(ctx, &name, &value)) { + return false; + } + + mie_attribute_map_put(out, name, value, 0); + free(name); + + while (1) { + if (!mie_parser_parse_symbol(ctx, MIE_SYM_COMMA)) { + break; + } + + if (!parse_attribute_map_entry(ctx, &name, &value)) { + return false; + } + + mie_attribute_map_put(out, name, value, 0); + free(name); + } + + return true; } diff --git a/mie/print/attribute.c b/mie/print/attribute.c new file mode 100644 index 0000000..a3a45d1 --- /dev/null +++ b/mie/print/attribute.c @@ -0,0 +1,10 @@ +#include +#include + +void mie_printer_print_attribute( + struct mie_printer *printer, const struct mie_attribute *attrib) +{ + if (attrib->a_def && attrib->a_def->a_print) { + attrib->a_def->a_print(attrib, printer); + } +} diff --git a/mie/print/op.c b/mie/print/op.c index c0ee908..82b3257 100644 --- a/mie/print/op.c +++ b/mie/print/op.c @@ -108,27 +108,34 @@ static void print_region_list(struct mie_printer *printer, const struct mie_op * } static void print_attribute( - struct mie_printer *printer, const struct mie_op_attribute *attrib) + struct mie_printer *printer, const struct mie_attribute_map_iterator *attrib) { - b_stream_write_fmt(printer->p_stream, NULL, "%s = ", attrib->attrib_name); - mie_printer_print_value(printer, attrib->attrib_value); + b_stream_write_fmt(printer->p_stream, NULL, "%s = ", attrib->it_name); + mie_printer_print_attribute(printer, attrib->it_value); } static void print_attribute_list( struct mie_printer *printer, const struct mie_op *op) { - if (!MIE_VECTOR_COUNT(op->op_attrib)) { + if (mie_attribute_map_empty(&op->op_attrib)) { return; } b_stream_write_string(printer->p_stream, " { ", NULL); - for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_attrib); i++) { + struct mie_attribute_map_iterator it; + enum mie_status status + = mie_attribute_map_iterator_begin(&it, &op->op_attrib); + size_t i = 0; + + while (status == MIE_SUCCESS) { if (i > 0) { b_stream_write_string(printer->p_stream, ", ", NULL); } - print_attribute(printer, &op->op_attrib.items[i]); + print_attribute(printer, &it); + status = mie_attribute_map_iterator_move_next(&it); + i++; } b_stream_write_string(printer->p_stream, " }", NULL); diff --git a/mie/print/value.c b/mie/print/value.c deleted file mode 100644 index 06ba4b3..0000000 --- a/mie/print/value.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include -#include - -void mie_printer_print_value( - struct mie_printer *printer, const struct mie_value *value) -{ - if (value->v_type && value->v_type->ty_def->ty_value_print) { - value->v_type->ty_def->ty_value_print(value, printer); - } -}