mie: type: implement function and storage types
This commit is contained in:
57
mie/ctx.c
57
mie/ctx.c
@@ -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(
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
94
mie/type/function.c
Normal 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
63
mie/type/storage.c
Normal 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);
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user