mie: type: implement function and storage types

This commit is contained in:
2026-01-08 19:17:34 +00:00
parent e98ccd0c80
commit 0a45e3b571
9 changed files with 310 additions and 13 deletions

View File

@@ -9,6 +9,8 @@
#include <mie/dialect/index.h> #include <mie/dialect/index.h>
#include <mie/dialect/type.h> #include <mie/dialect/type.h>
#include <mie/ir/op.h> #include <mie/ir/op.h>
#include <mie/type/function.h>
#include <mie/type/storage.h>
#include <mie/type/type.h> #include <mie/type/type.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -448,6 +450,61 @@ struct mie_type *mie_ctx_get_type(
return type; return type;
} }
struct mie_type *mie_ctx_get_storage_type(
struct mie_ctx *ctx, const struct mie_type **parts, size_t nr_parts)
{
struct mie_id_builder id_builder;
mie_id_builder_begin(&id_builder, &ctx->ctx_types.map_ns_id);
mie_storage_type_build_id(&id_builder, parts, nr_parts);
mie_id id;
mie_id_builder_end(&id_builder, &id);
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_storage_type *new_type = mie_storage_type_create();
for (size_t i = 0; i < nr_parts; i++) {
mie_storage_type_add_part(new_type, parts[i]);
}
new_type->st_base.ty_id = id;
mie_id_map_put_id(&ctx->ctx_types, &new_type->st_base.ty_id);
return (struct mie_type *)new_type;
}
struct mie_type *mie_ctx_get_function_type(
struct mie_ctx *ctx, const struct mie_type **in, size_t nr_in,
const struct mie_type **out, size_t nr_out)
{
struct mie_id_builder id_builder;
mie_id_builder_begin(&id_builder, &ctx->ctx_types.map_ns_id);
mie_function_type_build_id(&id_builder, in, nr_in, out, nr_out);
mie_id id;
mie_id_builder_end(&id_builder, &id);
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_function_type *new_type = mie_function_type_create();
for (size_t i = 0; i < nr_in; i++) {
mie_function_type_add_in_part(new_type, in[i]);
}
for (size_t i = 0; i < nr_out; i++) {
mie_function_type_add_out_part(new_type, out[i]);
}
new_type->func_base.ty_id = id;
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) 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( return (struct mie_value *)mie_int_cache_get(

View File

@@ -38,6 +38,11 @@ MIE_API struct mie_dialect_type *mie_ctx_get_dialect_type(
const struct mie_ctx *ctx, const char *dialect_name, const char *type_name); const struct mie_ctx *ctx, const char *dialect_name, const char *type_name);
MIE_API struct mie_type *mie_ctx_get_type( MIE_API struct mie_type *mie_ctx_get_type(
struct mie_ctx *ctx, const char *dialect_name, const char *type_name); struct mie_ctx *ctx, const char *dialect_name, const char *type_name);
MIE_API struct mie_type *mie_ctx_get_storage_type(
struct mie_ctx *ctx, const struct mie_type **parts, size_t nr_parts);
MIE_API struct mie_type *mie_ctx_get_function_type(
struct mie_ctx *ctx, const struct mie_type **in, size_t nr_in,
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_null(struct mie_ctx *ctx);
MIE_API struct mie_value *mie_ctx_get_int( MIE_API struct mie_value *mie_ctx_get_int(

View File

@@ -34,8 +34,7 @@ struct mie_dialect_type {
enum mie_status (*ty_parse)( enum mie_status (*ty_parse)(
const struct mie_dialect_type *, struct mie_parser *, const struct mie_dialect_type *, struct mie_parser *,
struct mie_type **); struct mie_type **);
void (*ty_init)(const struct mie_dialect_type *, struct mie_type *); void (*ty_build_id)(const struct mie_type *, struct mie_id_builder *);
void (*ty_cleanup)(const struct mie_dialect_type *, struct mie_type *);
}; };
MIE_API struct mie_dialect_type *mie_dialect_type_create( MIE_API struct mie_dialect_type *mie_dialect_type_create(

View File

@@ -1,20 +1,28 @@
#ifndef MIE_TYPE_FUNCTION_H_ #ifndef MIE_TYPE_FUNCTION_H_
#define MIE_TYPE_FUNCTION_H_ #define MIE_TYPE_FUNCTION_H_
#include <blue/core/stream.h>
#include <mie/type/type.h> #include <mie/type/type.h>
#include <mie/vector.h> #include <mie/vector.h>
struct mie_function_type { struct mie_function_type {
struct mie_type func_base; struct mie_type func_base;
MIE_VECTOR_DECLARE(struct mie_type *, func_in); MIE_VECTOR_DECLARE(const struct mie_type *, func_in);
MIE_VECTOR_DECLARE(struct mie_type *, func_out); MIE_VECTOR_DECLARE(const struct mie_type *, func_out);
}; };
MIE_API struct mie_function_type *mie_function_type_create(void); MIE_API struct mie_function_type *mie_function_type_create(void);
MIE_API void mie_function_type_add_in_part( MIE_API void mie_function_type_add_in_part(
struct mie_function_type *ty, struct mie_type *part); struct mie_function_type *ty, const struct mie_type *part);
MIE_API void mie_function_type_add_out_part( MIE_API void mie_function_type_add_out_part(
struct mie_function_type *ty, struct mie_type *part); struct mie_function_type *ty, const struct mie_type *part);
MIE_API void mie_function_type_print(
const struct mie_function_type *type, b_stream *out);
MIE_API void mie_function_type_build_id(
struct mie_id_builder *builder, const struct mie_type **in_types,
size_t nr_in_types, const struct mie_type **out_types,
size_t nr_out_types);
#endif #endif

View File

@@ -1,17 +1,24 @@
#ifndef MIE_TYPE_STORAGE_H_ #ifndef MIE_TYPE_STORAGE_H_
#define MIE_TYPE_STORAGE_H_ #define MIE_TYPE_STORAGE_H_
#include <blue/core/stream.h>
#include <mie/type/type.h> #include <mie/type/type.h>
#include <mie/vector.h> #include <mie/vector.h>
struct mie_storage_type { struct mie_storage_type {
struct mie_type st_base; struct mie_type st_base;
MIE_VECTOR_DECLARE(struct mie_type *, st_parts); MIE_VECTOR_DECLARE(const struct mie_type *, st_parts);
}; };
MIE_API struct mie_storage_type *mie_storage_type_create(void); MIE_API struct mie_storage_type *mie_storage_type_create(void);
MIE_API void mie_storage_type_add_part( MIE_API void mie_storage_type_add_part(
struct mie_storage_type *ty, struct mie_type *part); struct mie_storage_type *ty, const struct mie_type *part);
MIE_API void mie_storage_type_print(
const struct mie_storage_type *type, b_stream *out);
MIE_API void mie_storage_type_build_id(
struct mie_id_builder *builder, const struct mie_type **parts,
size_t nr_parts);
#endif #endif

View File

@@ -1,6 +1,8 @@
#ifndef MIE_TYPE_TYPE_H_ #ifndef MIE_TYPE_TYPE_H_
#define MIE_TYPE_TYPE_H_ #define MIE_TYPE_TYPE_H_
#include <blue/core/stream.h>
#include <blue/core/stringstream.h>
#include <mie/id.h> #include <mie/id.h>
#include <mie/misc.h> #include <mie/misc.h>
#include <stddef.h> #include <stddef.h>
@@ -9,6 +11,16 @@ struct mie_dialect;
struct mie_dialect_type; struct mie_dialect_type;
struct mie_value; struct mie_value;
struct mie_id_builder;
enum mie_type_category {
/* all other types */
MIE_TYPE_OTHER = 0,
/* storage types (structs, etc) */
MIE_TYPE_STORAGE,
/* functional types (represents the param/result types of a function) */
MIE_TYPE_FUNCTION,
};
/* a mie_type is an instance of mie_dialect_type. /* a mie_type is an instance of mie_dialect_type.
* if the mie_dialect_type is a parametised type, the resulting mie_type * if the mie_dialect_type is a parametised type, the resulting mie_type
@@ -18,18 +30,19 @@ struct mie_value;
struct mie_type { struct mie_type {
/* this is NOT the same as ty_def->ty_id */ /* this is NOT the same as ty_def->ty_id */
mie_id ty_id; mie_id ty_id;
enum mie_type_category ty_category;
/* this pointer is optional. if it is NULL, the name of the type can
* be found in ty_def */
char *ty_name; char *ty_name;
struct mie_dialect_type *ty_def; 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; size_t ty_instance_size;
}; };
MIE_API struct mie_type *mie_type_create(struct mie_dialect_type *type); MIE_API struct mie_type *mie_type_create(struct mie_dialect_type *type);
MIE_API void mie_type_print(const struct mie_type *type, b_stream *out);
MIE_API void mie_type_build_id(
const struct mie_type *type, struct mie_id_builder *ctx);
MIE_API void mie_type_generate_id(
const struct mie_type *type, const mie_id *ns, mie_id *out);
#endif #endif

94
mie/type/function.c Normal file
View File

@@ -0,0 +1,94 @@
#include <mie/dialect/type.h>
#include <mie/type/function.h>
#include <stdlib.h>
#include <string.h>
static void build_id(const struct mie_type *type, struct mie_id_builder *ctx)
{
const struct mie_function_type *function
= (const struct mie_function_type *)type;
mie_function_type_build_id(
ctx, function->func_in.items, function->func_in.count,
function->func_out.items, function->func_out.count);
}
static struct mie_dialect_type function_type = {
.ty_data_size = sizeof(struct mie_type),
.ty_build_id = build_id,
};
struct mie_function_type *mie_function_type_create(void)
{
struct mie_function_type *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->func_base.ty_def = &function_type;
out->func_base.ty_category = MIE_TYPE_FUNCTION;
return out;
}
void mie_function_type_add_in_part(
struct mie_function_type *ty, const struct mie_type *part)
{
mie_vector_push_back(ty->func_in, &part);
}
void mie_function_type_add_out_part(
struct mie_function_type *ty, const struct mie_type *part)
{
mie_vector_push_back(ty->func_out, &part);
}
void mie_function_type_print(const struct mie_function_type *type, b_stream *out)
{
b_stream_write_char(out, '(');
for (size_t i = 0; i < MIE_VECTOR_COUNT(type->func_in); i++) {
if (i > 0) {
b_stream_write_string(out, ", ", NULL);
}
mie_type_print(MIE_VECTOR_ITEM(type->func_in, i), out);
}
b_stream_write_string(out, ") -> ", NULL);
if (MIE_VECTOR_COUNT(type->func_out) == 1) {
mie_type_print(MIE_VECTOR_ITEM(type->func_out, 0), out);
return;
}
b_stream_write_char(out, '(');
for (size_t i = 0; i < MIE_VECTOR_COUNT(type->func_out); i++) {
if (i > 0) {
b_stream_write_string(out, ", ", NULL);
}
mie_type_print(MIE_VECTOR_ITEM(type->func_out, i), out);
}
b_stream_write_char(out, ')');
}
void mie_function_type_build_id(
struct mie_id_builder *ctx, const struct mie_type **in_types,
size_t nr_in_types, const struct mie_type **out_types, size_t nr_out_types)
{
mie_id_builder_add_marker(ctx, MIE_ID_BUILDER_FUNCTION_IN_START);
for (size_t i = 0; i < nr_in_types; i++) {
mie_type_build_id(in_types[i], ctx);
}
mie_id_builder_add_marker(ctx, MIE_ID_BUILDER_FUNCTION_IN_END);
mie_id_builder_add_marker(ctx, MIE_ID_BUILDER_FUNCTION_OUT_START);
for (size_t i = 0; i < nr_out_types; i++) {
mie_type_build_id(out_types[i], ctx);
}
mie_id_builder_add_marker(ctx, MIE_ID_BUILDER_FUNCTION_OUT_END);
}

63
mie/type/storage.c Normal file
View File

@@ -0,0 +1,63 @@
#include <mie/dialect/type.h>
#include <mie/type/storage.h>
#include <stdlib.h>
#include <string.h>
static void build_id(const struct mie_type *type, struct mie_id_builder *ctx)
{
const struct mie_storage_type *storage
= (const struct mie_storage_type *)type;
mie_storage_type_build_id(
ctx, storage->st_parts.items, storage->st_parts.count);
}
static struct mie_dialect_type storage_type = {
.ty_data_size = sizeof(struct mie_type),
.ty_build_id = build_id,
};
struct mie_storage_type *mie_storage_type_create(void)
{
struct mie_storage_type *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->st_base.ty_def = &storage_type;
out->st_base.ty_category = MIE_TYPE_STORAGE;
return out;
}
void mie_storage_type_add_part(
struct mie_storage_type *ty, const struct mie_type *part)
{
mie_vector_push_back(ty->st_parts, &part);
}
void mie_storage_type_print(const struct mie_storage_type *type, b_stream *out)
{
b_stream_write_char(out, '(');
for (size_t i = 0; i < MIE_VECTOR_COUNT(type->st_parts); i++) {
if (i > 0) {
b_stream_write_string(out, ", ", NULL);
}
mie_type_print(MIE_VECTOR_ITEM(type->st_parts, i), out);
}
b_stream_write_char(out, ')');
}
void mie_storage_type_build_id(
struct mie_id_builder *ctx, const struct mie_type **parts, size_t nr_parts)
{
mie_id_builder_add_marker(ctx, MIE_ID_BUILDER_STORAGE_START);
for (size_t i = 0; i < nr_parts; i++) {
mie_type_build_id(parts[i], ctx);
}
mie_id_builder_add_marker(ctx, MIE_ID_BUILDER_STORAGE_END);
}

View File

@@ -1,4 +1,6 @@
#include <mie/dialect/type.h> #include <mie/dialect/type.h>
#include <mie/type/function.h>
#include <mie/type/storage.h>
#include <mie/type/type.h> #include <mie/type/type.h>
struct mie_type *mie_type_create(struct mie_dialect_type *type) struct mie_type *mie_type_create(struct mie_dialect_type *type)
@@ -17,3 +19,52 @@ struct mie_type *mie_type_create(struct mie_dialect_type *type)
return out; return out;
} }
void mie_type_print(const struct mie_type *type, b_stream *out)
{
switch (type->ty_category) {
case MIE_TYPE_STORAGE:
mie_storage_type_print((const struct mie_storage_type *)type, out);
return;
case MIE_TYPE_FUNCTION:
mie_function_type_print((const struct mie_function_type *)type, out);
return;
default:
break;
}
if (type->ty_name) {
b_stream_write_string(out, type->ty_name, NULL);
} else if (type->ty_def && type->ty_def->ty_print) {
type->ty_def->ty_print(type->ty_def, type, out);
} else if (type->ty_def->ty_name) {
b_stream_write_string(out, type->ty_def->ty_name, NULL);
} else {
b_stream_write_string(out, "<UNNAMED-TYPE>", NULL);
}
}
void mie_type_build_id(const struct mie_type *type, struct mie_id_builder *ctx)
{
if (type->ty_def->ty_build_id) {
type->ty_def->ty_build_id(type, ctx);
return;
} else if (type->ty_name) {
mie_id_builder_add(ctx, type->ty_name, strlen(type->ty_name));
} else if (type->ty_def->ty_name) {
mie_id_builder_add(
ctx, type->ty_def->ty_name, strlen(type->ty_def->ty_name));
} else {
const char *placeholder = "<UNNAMED-TYPE>";
const size_t placeholder_len = strlen(placeholder);
mie_id_builder_add(ctx, placeholder, placeholder_len);
}
}
void mie_type_generate_id(const struct mie_type *type, const mie_id *ns, mie_id *out)
{
struct mie_id_builder ctx;
mie_id_builder_begin(&ctx, ns);
mie_type_build_id(type, &ctx);
mie_id_builder_end(&ctx, out);
}