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); - } -}