From 9126edfd570f6ce71dd7d360ffe49a0ff3868a43 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 4 Jan 2026 18:42:12 +0000 Subject: [PATCH] mie: ctx: implement generic (non-parametised) type initialisation --- mie/ctx.c | 48 ++++++++++++++++++++++++++++++++++ mie/include/mie/ctx.h | 2 ++ mie/include/mie/dialect/type.h | 5 ++++ mie/include/mie/macros.h | 1 + mie/include/mie/type/type.h | 12 +++++++-- mie/type/type.c | 19 ++++++++++++++ 6 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 mie/type/type.c diff --git a/mie/ctx.c b/mie/ctx.c index 81a9f34..41ece63 100644 --- a/mie/ctx.c +++ b/mie/ctx.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -391,3 +392,50 @@ struct mie_dialect_type *mie_ctx_get_dialect_type( return b_unbox(struct mie_dialect_type, target, ty_id); } + +struct mie_type *mie_ctx_get_type( + struct mie_ctx *ctx, const char *dialect_name, const char *type_name) +{ + char full_name[256]; + snprintf(full_name, sizeof full_name, "%s.%s", dialect_name, dialect_name); + b_rope full_name_rope = B_ROPE_CSTR(full_name); + + mie_id id; + mie_id_init_ns(&id, mie_id_map_get_ns(&ctx->ctx_types), &full_name_rope); + + mie_id *target = mie_id_map_get(&ctx->ctx_types, &id); + struct mie_type *type = b_unbox(struct mie_type, target, ty_id); + if (type) { + return type; + } + + struct mie_dialect_type *type_info + = mie_ctx_get_dialect_type(ctx, dialect_name, type_name); + if (!type_info || (type_info->ty_flags & MIE_DIALECT_TYPE_PARAMETISED)) { + /* cannot initialise unknown or parametised types */ + return NULL; + } + + if (type_info->ty_data_size < sizeof(struct mie_type)) { + /* invalid type info */ + return NULL; + } + + type = malloc(type_info->ty_data_size); + if (!type) { + return NULL; + } + + memset(type, 0x0, sizeof *type); + + type->ty_def = type_info; + type->ty_name = b_bstr_fmt("%s.%s", dialect_name, type_name); + + if (type_info->ty_init) { + type_info->ty_init(type_info, type); + } + + mie_id_map_put(&ctx->ctx_types, &type->ty_id, &full_name_rope); + + return type; +} diff --git a/mie/include/mie/ctx.h b/mie/include/mie/ctx.h index 72fd328..5ba9b23 100644 --- a/mie/include/mie/ctx.h +++ b/mie/include/mie/ctx.h @@ -31,6 +31,8 @@ MIE_API struct mie_dialect *mie_ctx_get_dialect( const struct mie_ctx *ctx, const char *name); MIE_API struct mie_dialect_type *mie_ctx_get_dialect_type( const struct mie_ctx *ctx, const char *dialect_name, const char *type_name); +MIE_API struct mie_type *mie_ctx_get_type( + struct mie_ctx *ctx, const char *dialect_name, const char *type_name); MIE_API struct mie_type *mie_ctx_get_int_type( struct mie_ctx *ctx, unsigned int nr_bits); diff --git a/mie/include/mie/dialect/type.h b/mie/include/mie/dialect/type.h index 780ff38..6b37eef 100644 --- a/mie/include/mie/dialect/type.h +++ b/mie/include/mie/dialect/type.h @@ -10,8 +10,13 @@ struct mie_type; struct mie_parser; struct mie_dialect; +enum mie_dialect_type_flags { + MIE_DIALECT_TYPE_PARAMETISED = 0x01u, +}; + struct mie_dialect_type { mie_id ty_id; + enum mie_dialect_type_flags ty_flags; struct mie_dialect *ty_parent; char *ty_name; diff --git a/mie/include/mie/macros.h b/mie/include/mie/macros.h index 0949012..a102c89 100644 --- a/mie/include/mie/macros.h +++ b/mie/include/mie/macros.h @@ -62,6 +62,7 @@ __MIE_DIALECT_TYPE_BEGIN(c_sym, type) #define MIE_DIALECT_TYPE_END() __MIE_DIALECT_TYPE_END() #define MIE_DIALECT_TYPE_STRUCT(name) type->ty_data_size = sizeof(name) +#define MIE_DIALECT_TYPE_INIT(func) type->ty_init = (func) #define MIE_DIALECT_TYPE_PRINT(func) type->ty_print = (func) #define MIE_DIALECT_TYPE_PARSE(func) type->ty_parse = (func) #define MIE_DIALECT_TYPE_INIT(func) type->ty_init = (func) diff --git a/mie/include/mie/type/type.h b/mie/include/mie/type/type.h index 9cb7e12..aab41a0 100644 --- a/mie/include/mie/type/type.h +++ b/mie/include/mie/type/type.h @@ -8,7 +8,7 @@ struct mie_dialect; struct mie_dialect_type; -struct mie_type; +struct mie_value; /* a mie_type is an instance of mie_dialect_type. * if the mie_dialect_type is a parametised type, the resulting mie_type @@ -22,8 +22,16 @@ struct mie_type { /* this pointer is optional. if it is NULL, the name of the type can * be found in ty_def */ char *ty_name; - struct mie_dialect_type *ty_def; + + /* for types that can be instantiated in C (i.e. an instance that can + * be represented by a mie_value), this is the total size of the + * instance data. */ + size_t ty_instance_size; + + void (*ty_instance_cleanup)(const struct mie_type *, struct mie_value *); + void (*ty_value_print)( + const struct mie_type *, const struct mie_value *, b_stream *); }; MIE_API struct mie_type *mie_type_create(struct mie_dialect_type *type); diff --git a/mie/type/type.c b/mie/type/type.c new file mode 100644 index 0000000..562266d --- /dev/null +++ b/mie/type/type.c @@ -0,0 +1,19 @@ +#include +#include + +struct mie_type *mie_type_create(struct mie_dialect_type *type) +{ + if (type->ty_data_size < sizeof(struct mie_type)) { + return NULL; + } + + struct mie_type *out = malloc(type->ty_data_size); + if (!out) { + return NULL; + } + + memset(out, 0x0, sizeof *out); + out->ty_def = type; + + return out; +}