mie: add support for adding traits to types and ops
This commit is contained in:
353
mie/ctx.c
353
mie/ctx.c
@@ -8,6 +8,8 @@
|
|||||||
#include <mie/dialect/dialect.h>
|
#include <mie/dialect/dialect.h>
|
||||||
#include <mie/dialect/index.h>
|
#include <mie/dialect/index.h>
|
||||||
#include <mie/ir/op.h>
|
#include <mie/ir/op.h>
|
||||||
|
#include <mie/trait/trait-definition.h>
|
||||||
|
#include <mie/trait/trait.h>
|
||||||
#include <mie/type/function.h>
|
#include <mie/type/function.h>
|
||||||
#include <mie/type/storage.h>
|
#include <mie/type/storage.h>
|
||||||
#include <mie/type/type-definition.h>
|
#include <mie/type/type-definition.h>
|
||||||
@@ -23,285 +25,6 @@
|
|||||||
MIE_ID(0xf5, 0x4e, 0xc5, 0x8c, 0xc0, 0x1e, 0x48, 0x47, 0xb5, 0xf4, \
|
MIE_ID(0xf5, 0x4e, 0xc5, 0x8c, 0xc0, 0x1e, 0x48, 0x47, 0xb5, 0xf4, \
|
||||||
0x7b, 0xb9, 0x6b, 0x47, 0xca, 0x48)
|
0x7b, 0xb9, 0x6b, 0x47, 0xca, 0x48)
|
||||||
|
|
||||||
struct ctx_int_cache_entry {
|
|
||||||
b_btree_node i_node;
|
|
||||||
// struct mie_type i_type;
|
|
||||||
b_btree i_values;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ctx_int_value_cache_entry {
|
|
||||||
b_btree_node i_node;
|
|
||||||
// struct mie_int i_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
B_BTREE_DEFINE_SIMPLE_INSERT(
|
|
||||||
struct ctx_int_cache_entry, i_node, i_type.t_width, put_cached_int_type)
|
|
||||||
B_BTREE_DEFINE_SIMPLE_GET(
|
|
||||||
struct ctx_int_cache_entry, unsigned int, i_node, i_type.t_width,
|
|
||||||
get_cached_int_type)
|
|
||||||
|
|
||||||
B_BTREE_DEFINE_SIMPLE_INSERT(
|
|
||||||
struct ctx_int_value_cache_entry, i_node, i_value.i_value,
|
|
||||||
put_cached_int_value)
|
|
||||||
B_BTREE_DEFINE_SIMPLE_GET(
|
|
||||||
struct ctx_int_value_cache_entry, int64_t, i_node, i_value.i_value,
|
|
||||||
get_cached_int_value)
|
|
||||||
|
|
||||||
struct mie_ctx *mie_ctx_create(void)
|
|
||||||
{
|
|
||||||
struct mie_ctx *out = malloc(sizeof *out);
|
|
||||||
|
|
||||||
if (!out) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(out, 0x0, sizeof *out);
|
|
||||||
|
|
||||||
out->ctx_true = MIE_CONST(mie_ctx_get_int(out, 1, 1));
|
|
||||||
out->ctx_false = MIE_CONST(mie_ctx_get_int(out, 0, 1));
|
|
||||||
|
|
||||||
out->ctx_null = malloc(sizeof *out->ctx_null);
|
|
||||||
if (!out->ctx_null) {
|
|
||||||
mie_ctx_destroy(out);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mie_value_init(out->ctx_null, MIE_VALUE_NONE);
|
|
||||||
|
|
||||||
out->ctx_sel_cache = b_hashmap_create(free, free);
|
|
||||||
out->ctx_string_cache = b_hashmap_create(free, free);
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mie_ctx_destroy(struct mie_ctx *ctx)
|
|
||||||
{
|
|
||||||
ctx->ctx_true = NULL;
|
|
||||||
ctx->ctx_false = NULL;
|
|
||||||
|
|
||||||
b_btree_node *node = b_btree_first(&ctx->ctx_int_cache);
|
|
||||||
while (node) {
|
|
||||||
struct ctx_int_cache_entry *entry
|
|
||||||
= b_unbox(struct ctx_int_cache_entry, node, i_node);
|
|
||||||
b_btree_node *next = b_btree_next(node);
|
|
||||||
b_btree_delete(&ctx->ctx_int_cache, node);
|
|
||||||
|
|
||||||
b_btree_node *node2 = b_btree_first(&entry->i_values);
|
|
||||||
while (node2) {
|
|
||||||
struct ctx_int_value_cache_entry *value = b_unbox(
|
|
||||||
struct ctx_int_value_cache_entry, node2, i_node);
|
|
||||||
b_btree_node *next2 = b_btree_next(node2);
|
|
||||||
b_btree_delete(&entry->i_values, node2);
|
|
||||||
free(value);
|
|
||||||
node2 = next2;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(entry);
|
|
||||||
node = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t nr_types = sizeof ctx->ctx_types / sizeof ctx->ctx_types[0];
|
|
||||||
for (size_t i = 0; i < nr_types; i++) {
|
|
||||||
if (ctx->ctx_types[i]) {
|
|
||||||
mie_value_destroy(MIE_VALUE(ctx->ctx_types[i]));
|
|
||||||
ctx->ctx_types[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx->ctx_null) {
|
|
||||||
mie_value_destroy(ctx->ctx_null);
|
|
||||||
}
|
|
||||||
|
|
||||||
b_hashmap_unref(ctx->ctx_sel_cache);
|
|
||||||
|
|
||||||
free(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mie_type *mie_ctx_get_type(struct mie_ctx *ctx, enum mie_type_id type_id)
|
|
||||||
{
|
|
||||||
if (type_id == MIE_TYPE_INT) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx->ctx_types[type_id]) {
|
|
||||||
return ctx->ctx_types[type_id];
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mie_type *type = mie_type_create();
|
|
||||||
if (!type) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
type->t_id = type_id;
|
|
||||||
|
|
||||||
ctx->ctx_types[type_id] = type;
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mie_value *mie_ctx_get_null(struct mie_ctx *ctx)
|
|
||||||
{
|
|
||||||
return ctx->ctx_null;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mie_type *mie_ctx_get_int_type(struct mie_ctx *ctx, unsigned int nr_bits)
|
|
||||||
{
|
|
||||||
struct ctx_int_cache_entry *entry
|
|
||||||
= get_cached_int_type(&ctx->ctx_int_cache, nr_bits);
|
|
||||||
|
|
||||||
if (entry) {
|
|
||||||
return &entry->i_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
entry = malloc(sizeof *entry);
|
|
||||||
if (!entry) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(entry, 0x0, sizeof *entry);
|
|
||||||
|
|
||||||
entry->i_type.t_id = MIE_TYPE_INT;
|
|
||||||
entry->i_type.t_width = nr_bits;
|
|
||||||
|
|
||||||
put_cached_int_type(&ctx->ctx_int_cache, entry);
|
|
||||||
return &entry->i_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mie_value *mie_ctx_get_bool(struct mie_ctx *ctx, bool val)
|
|
||||||
{
|
|
||||||
return MIE_VALUE(val ? ctx->ctx_true : ctx->ctx_false);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mie_value *mie_ctx_get_int(
|
|
||||||
struct mie_ctx *ctx, long long val, unsigned int nr_bits)
|
|
||||||
{
|
|
||||||
struct ctx_int_cache_entry *entry
|
|
||||||
= get_cached_int_type(&ctx->ctx_int_cache, nr_bits);
|
|
||||||
|
|
||||||
if (!entry) {
|
|
||||||
entry = malloc(sizeof *entry);
|
|
||||||
if (!entry) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(entry, 0x0, sizeof *entry);
|
|
||||||
|
|
||||||
entry->i_type.t_id = MIE_TYPE_INT;
|
|
||||||
entry->i_type.t_width = nr_bits;
|
|
||||||
|
|
||||||
put_cached_int_type(&ctx->ctx_int_cache, entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ctx_int_value_cache_entry *value
|
|
||||||
= get_cached_int_value(&entry->i_values, val);
|
|
||||||
if (value) {
|
|
||||||
return MIE_VALUE(&value->i_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
value = malloc(sizeof *value);
|
|
||||||
if (!value) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(value, 0x0, sizeof *value);
|
|
||||||
|
|
||||||
mie_const_init(&value->i_value.i_base, &entry->i_type);
|
|
||||||
value->i_value.i_value = val;
|
|
||||||
|
|
||||||
put_cached_int_value(&entry->i_values, value);
|
|
||||||
|
|
||||||
return MIE_VALUE(&value->i_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mie_value *mie_ctx_get_selector(struct mie_ctx *ctx, const char *sel)
|
|
||||||
{
|
|
||||||
b_hashmap_key key = {
|
|
||||||
.key_data = sel,
|
|
||||||
.key_size = strlen(sel),
|
|
||||||
};
|
|
||||||
|
|
||||||
const b_hashmap_value *cache_entry
|
|
||||||
= b_hashmap_get(ctx->ctx_sel_cache, &key);
|
|
||||||
|
|
||||||
if (cache_entry) {
|
|
||||||
return cache_entry->value_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mie_selector *sel_value = malloc(sizeof *sel_value);
|
|
||||||
if (!sel_value) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mie_type *sel_type = mie_ctx_get_type(ctx, MIE_TYPE_SELECTOR);
|
|
||||||
mie_const_init(&sel_value->sel_base, sel_type);
|
|
||||||
sel_value->sel_value = b_strdup(sel);
|
|
||||||
|
|
||||||
key.key_data = sel_value->sel_value;
|
|
||||||
|
|
||||||
b_hashmap_value hashmap_value = {
|
|
||||||
.value_data = sel_value,
|
|
||||||
.value_size = sizeof *sel_value,
|
|
||||||
};
|
|
||||||
|
|
||||||
b_hashmap_put(ctx->ctx_sel_cache, &key, &hashmap_value);
|
|
||||||
|
|
||||||
return MIE_VALUE(sel_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mie_value *mie_ctx_get_string(struct mie_ctx *ctx, const char *s)
|
|
||||||
{
|
|
||||||
b_hashmap_key key = {
|
|
||||||
.key_data = s,
|
|
||||||
.key_size = strlen(s),
|
|
||||||
};
|
|
||||||
|
|
||||||
const b_hashmap_value *cache_entry
|
|
||||||
= b_hashmap_get(ctx->ctx_string_cache, &key);
|
|
||||||
|
|
||||||
if (cache_entry) {
|
|
||||||
return cache_entry->value_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mie_string *string_value = malloc(sizeof *string_value);
|
|
||||||
if (!string_value) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mie_type *string_type = mie_ctx_get_type(ctx, MIE_TYPE_STR);
|
|
||||||
mie_const_init(&string_value->s_base, string_type);
|
|
||||||
string_value->s_value = b_strdup(s);
|
|
||||||
|
|
||||||
key.key_data = string_value->s_value;
|
|
||||||
|
|
||||||
b_hashmap_value hashmap_value = {
|
|
||||||
.value_data = string_value,
|
|
||||||
.value_size = sizeof *string_value,
|
|
||||||
};
|
|
||||||
|
|
||||||
b_hashmap_put(ctx->ctx_string_cache, &key, &hashmap_value);
|
|
||||||
|
|
||||||
return MIE_VALUE(string_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mie_value *mie_ctx_create_array(struct mie_ctx *ctx)
|
|
||||||
{
|
|
||||||
struct mie_type *array_type = mie_ctx_get_type(ctx, MIE_TYPE_ARRAY);
|
|
||||||
struct mie_array *array = malloc(sizeof *array);
|
|
||||||
|
|
||||||
if (!array) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(array, 0x0, sizeof *array);
|
|
||||||
mie_const_init(&array->a_base, array_type);
|
|
||||||
|
|
||||||
array->a_values = b_list_create();
|
|
||||||
|
|
||||||
return MIE_VALUE(array);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct mie_ctx *mie_ctx_create(void)
|
struct mie_ctx *mie_ctx_create(void)
|
||||||
{
|
{
|
||||||
struct mie_ctx *out = malloc(sizeof *out);
|
struct mie_ctx *out = malloc(sizeof *out);
|
||||||
@@ -328,7 +51,7 @@ struct mie_ctx *mie_ctx_create(void)
|
|||||||
bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
|
bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
|
||||||
{
|
{
|
||||||
bool fully_resolved = MIE_TEST_FLAGS(
|
bool fully_resolved = MIE_TEST_FLAGS(
|
||||||
op->op_flags, MIE_OP_F_OP_RESOLVED | MIE_OP_F_ARGS_RESOLVED);
|
op->op_flags, MIE_OP_F_OP_RESOLVED | MIE_OP_F_ARG_RESOLVED);
|
||||||
|
|
||||||
if (fully_resolved) {
|
if (fully_resolved) {
|
||||||
return true;
|
return true;
|
||||||
@@ -406,11 +129,32 @@ struct mie_type_definition *mie_ctx_get_type_definition(
|
|||||||
return b_unbox(struct mie_type_definition, target, ty_id);
|
return b_unbox(struct mie_type_definition, target, ty_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const struct mie_trait_definition *mie_ctx_get_trait_definition(
|
||||||
|
const struct mie_ctx *ctx, const char *dialect_name, const char *trait_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 trait_name_rope = B_ROPE_CSTR(trait_name);
|
||||||
|
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_traits), &trait_name_rope);
|
||||||
|
target = mie_id_map_get(&dialect->d_traits, &id);
|
||||||
|
|
||||||
|
return b_unbox(struct mie_trait_definition, target, tr_id);
|
||||||
|
}
|
||||||
|
|
||||||
struct mie_type *mie_ctx_get_type(
|
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)
|
||||||
{
|
{
|
||||||
char full_name[256];
|
char full_name[256];
|
||||||
snprintf(full_name, sizeof full_name, "%s.%s", dialect_name, dialect_name);
|
snprintf(full_name, sizeof full_name, "%s.%s", dialect_name, type_name);
|
||||||
b_rope full_name_rope = B_ROPE_CSTR(full_name);
|
b_rope full_name_rope = B_ROPE_CSTR(full_name);
|
||||||
|
|
||||||
mie_id id;
|
mie_id id;
|
||||||
@@ -453,6 +197,53 @@ struct mie_type *mie_ctx_get_type(
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const struct mie_trait *mie_ctx_get_trait(
|
||||||
|
struct mie_ctx *ctx, const char *dialect_name, const char *trait_name)
|
||||||
|
{
|
||||||
|
char full_name[256];
|
||||||
|
snprintf(full_name, sizeof full_name, "%s.%s", dialect_name, trait_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_traits), &full_name_rope);
|
||||||
|
|
||||||
|
mie_id *target = mie_id_map_get(&ctx->ctx_traits, &id);
|
||||||
|
struct mie_trait *trait = b_unbox(struct mie_trait, target, tr_id);
|
||||||
|
if (trait) {
|
||||||
|
return trait;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct mie_trait_definition *trait_info
|
||||||
|
= mie_ctx_get_trait_definition(ctx, dialect_name, trait_name);
|
||||||
|
if (!trait_info /* || (trait_info->ty_flags & MIE_DIALECT_TYPE_PARAMETISED) */) {
|
||||||
|
/* cannot initialise unknown or parametised traits */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trait_info->tr_data_size < sizeof(struct mie_trait)) {
|
||||||
|
/* invalid trait info */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait = malloc(trait_info->tr_data_size);
|
||||||
|
if (!trait) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(trait, 0x0, sizeof *trait);
|
||||||
|
|
||||||
|
trait->tr_def = trait_info;
|
||||||
|
trait->tr_name = b_bstr_fmt("%s.%s", dialect_name, trait_name);
|
||||||
|
|
||||||
|
if (trait_info->tr_init) {
|
||||||
|
trait_info->tr_init(trait_info, trait);
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_id_map_put(&ctx->ctx_traits, &trait->tr_id, &full_name_rope);
|
||||||
|
|
||||||
|
return trait;
|
||||||
|
}
|
||||||
|
|
||||||
struct mie_type *mie_ctx_get_storage_type(
|
struct mie_type *mie_ctx_get_storage_type(
|
||||||
struct mie_ctx *ctx, const struct mie_type **parts, size_t nr_parts)
|
struct mie_ctx *ctx, const struct mie_type **parts, size_t nr_parts)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,9 +40,12 @@ MIE_API struct mie_dialect *mie_ctx_get_dialect(
|
|||||||
const struct mie_ctx *ctx, const char *name);
|
const struct mie_ctx *ctx, const char *name);
|
||||||
MIE_API struct mie_type_definition *mie_ctx_get_type_definition(
|
MIE_API struct mie_type_definition *mie_ctx_get_type_definition(
|
||||||
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 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 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_trait(
|
MIE_API const struct mie_trait *mie_ctx_get_trait(
|
||||||
struct mie_ctx *ctx, const char *dialect_name, const char *trait_name);
|
struct mie_ctx *ctx, const char *dialect_name, const char *trait_name);
|
||||||
MIE_API struct mie_type *mie_ctx_get_storage_type(
|
MIE_API struct mie_type *mie_ctx_get_storage_type(
|
||||||
struct mie_ctx *ctx, const struct mie_type **parts, size_t nr_parts);
|
struct mie_ctx *ctx, const struct mie_type **parts, size_t nr_parts);
|
||||||
|
|||||||
@@ -106,4 +106,7 @@ struct mie_op_definition {
|
|||||||
MIE_API struct mie_op_definition *mie_op_definition_create(
|
MIE_API struct mie_op_definition *mie_op_definition_create(
|
||||||
struct mie_dialect *parent, const char *name);
|
struct mie_dialect *parent, const char *name);
|
||||||
|
|
||||||
|
MIE_API enum mie_status mie_op_definition_add_trait(
|
||||||
|
struct mie_op_definition *op, const struct mie_trait *trait);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
return NULL; \
|
return NULL; \
|
||||||
} \
|
} \
|
||||||
struct mie_op_definition *op = NULL; \
|
struct mie_op_definition *op = NULL; \
|
||||||
struct mie_type_definition *type = NULL;
|
struct mie_type_definition *type = NULL; \
|
||||||
|
struct mie_trait_definition *trait = NULL;
|
||||||
|
|
||||||
#define __MIE_DIALECT_END() \
|
#define __MIE_DIALECT_END() \
|
||||||
return self; \
|
return self; \
|
||||||
@@ -23,7 +24,8 @@
|
|||||||
= mie_op_definition_create(d, op_name); \
|
= mie_op_definition_create(d, op_name); \
|
||||||
if (!op) { \
|
if (!op) { \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
}
|
} \
|
||||||
|
const struct mie_trait *trait = NULL;
|
||||||
|
|
||||||
#define __MIE_OP_DEFINITION_END() \
|
#define __MIE_OP_DEFINITION_END() \
|
||||||
return op; \
|
return op; \
|
||||||
@@ -37,7 +39,8 @@
|
|||||||
= mie_type_definition_create(d, type_name); \
|
= mie_type_definition_create(d, type_name); \
|
||||||
if (!type) { \
|
if (!type) { \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
}
|
} \
|
||||||
|
const struct mie_trait *trait = NULL;
|
||||||
|
|
||||||
#define __MIE_TYPE_DEFINITION_END() \
|
#define __MIE_TYPE_DEFINITION_END() \
|
||||||
return type; \
|
return type; \
|
||||||
@@ -66,9 +69,9 @@
|
|||||||
struct mie_dialect *, struct mie_ctx *); \
|
struct mie_dialect *, struct mie_ctx *); \
|
||||||
type = type_id##_type_create(self, ctx)
|
type = type_id##_type_create(self, ctx)
|
||||||
#define __MIE_DIALECT_ADD_TRAIT(trait_id) \
|
#define __MIE_DIALECT_ADD_TRAIT(trait_id) \
|
||||||
extern struct mie_trait_definition *type_id##_trait_create( \
|
extern struct mie_trait_definition *trait_id##_trait_create( \
|
||||||
struct mie_dialect *, struct mie_ctx *); \
|
struct mie_dialect *, struct mie_ctx *); \
|
||||||
type = type_id##_trait_create(self, ctx)
|
trait = trait_id##_trait_create(self, ctx)
|
||||||
|
|
||||||
#define MIE_DIALECT_BEGIN(c_sym, name) __MIE_DIALECT_BEGIN(c_sym, name)
|
#define MIE_DIALECT_BEGIN(c_sym, name) __MIE_DIALECT_BEGIN(c_sym, name)
|
||||||
#define MIE_DIALECT_END() __MIE_DIALECT_END()
|
#define MIE_DIALECT_END() __MIE_DIALECT_END()
|
||||||
@@ -80,6 +83,9 @@
|
|||||||
#define MIE_OP_DEFINITION_END() __MIE_OP_DEFINITION_END()
|
#define MIE_OP_DEFINITION_END() __MIE_OP_DEFINITION_END()
|
||||||
#define MIE_OP_DEFINITION_PRINT(func) op->op_print = (func)
|
#define MIE_OP_DEFINITION_PRINT(func) op->op_print = (func)
|
||||||
#define MIE_OP_DEFINITION_PARSE(func) op->op_parse = (func)
|
#define MIE_OP_DEFINITION_PARSE(func) op->op_parse = (func)
|
||||||
|
#define MIE_OP_DEFINITION_TRAIT(trait_dialect, trait_name) \
|
||||||
|
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
|
||||||
|
mie_op_definition_add_trait(op, trait);
|
||||||
|
|
||||||
#define MIE_TYPE_DEFINITION_BEGIN(c_sym, type) \
|
#define MIE_TYPE_DEFINITION_BEGIN(c_sym, type) \
|
||||||
__MIE_TYPE_DEFINITION_BEGIN(c_sym, type)
|
__MIE_TYPE_DEFINITION_BEGIN(c_sym, type)
|
||||||
@@ -93,14 +99,18 @@
|
|||||||
#define MIE_TYPE_DEFINITION_BUILD_ID(func) type->ty_build_id = (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_INIT(func) type->ty_init = (func)
|
||||||
#define MIE_TYPE_DEFINITION_CLEANUP(func) type->ty_cleanup = (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);
|
||||||
|
|
||||||
#define MIE_TRAIT_DEFINITION_BEGIN(c_sym, trait) \
|
#define MIE_TRAIT_DEFINITION_BEGIN(c_sym, trait) \
|
||||||
__MIE_TRAIT_DEFINITION_BEGIN(c_sym, trait)
|
__MIE_TRAIT_DEFINITION_BEGIN(c_sym, trait)
|
||||||
#define MIE_TRAIT_DEFINITION_END() __MIE_TRAIT_DEFINITION_END()
|
#define MIE_TRAIT_DEFINITION_END() __MIE_TRAIT_DEFINITION_END()
|
||||||
|
#define MIE_TRAIT_DEFINITION_TARGETS(targets) trait->tr_target = (targets)
|
||||||
#define MIE_TRAIT_DEFINITION_STRUCT(name) trait->tr_data_size = sizeof(name)
|
#define MIE_TRAIT_DEFINITION_STRUCT(name) trait->tr_data_size = sizeof(name)
|
||||||
#define MIE_TRAIT_DEFINITION_PRINT(func) trait->tr_print = (func)
|
#define MIE_TRAIT_DEFINITION_PRINT(func) trait->tr_print = (func)
|
||||||
#define MIE_TRAIT_DEFINITION_BUILD_ID(func) trait->tr_build_id = (func)
|
#define MIE_TRAIT_DEFINITION_BUILD_ID(func) trait->tr_build_id = (func)
|
||||||
#define MIE_TRAIT_DEFINITION_CLEANUP(func) trait->tr_cleanup(func)
|
#define MIE_TRAIT_DEFINITION_CLEANUP(func) trait->tr_cleanup = (func)
|
||||||
#define MIE_TRAIT_DEFINITION_VALIDATE(func) trait->tr_validate(func)
|
#define MIE_TRAIT_DEFINITION_VALIDATE(func) trait->tr_validate = (func)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
64
mie/include/mie/trait/trait-definition.h
Normal file
64
mie/include/mie/trait/trait-definition.h
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#ifndef MIE_TRAIT_TRAIT_DEFINITION_H_
|
||||||
|
#define MIE_TRAIT_TRAIT_DEFINITION_H_
|
||||||
|
|
||||||
|
#include <blue/core/stream.h>
|
||||||
|
#include <mie/id.h>
|
||||||
|
#include <mie/status.h>
|
||||||
|
|
||||||
|
struct mie_trait;
|
||||||
|
struct mie_dialect;
|
||||||
|
|
||||||
|
enum mie_trait_flags {
|
||||||
|
/* a trait user can only apply the trait once. this is assumed to be the
|
||||||
|
* case unless a trait is parametised, in which case this flag can be
|
||||||
|
* used to prevent more than one specialisation from being used. */
|
||||||
|
MIE_TRAIT_F_UNIQUE = 0x01u,
|
||||||
|
MIE_TRAIT_F_PARAMETISED = 0x02u,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* describe exactly which objects a trait can be applied to */
|
||||||
|
enum mie_trait_target_type {
|
||||||
|
MIE_TRAIT_TARGET_NONE = 0x00u,
|
||||||
|
MIE_TRAIT_TARGET_OP = 0x01u,
|
||||||
|
MIE_TRAIT_TARGET_TYPE = 0x02u,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mie_trait_target {
|
||||||
|
enum mie_trait_target_type target_type;
|
||||||
|
union {
|
||||||
|
const struct mie_type *ptr_type;
|
||||||
|
const struct mie_op *ptr_op;
|
||||||
|
} target_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* used to define a trait */
|
||||||
|
struct mie_trait_definition {
|
||||||
|
/* ID for the generic trait */
|
||||||
|
mie_id tr_id;
|
||||||
|
char *tr_name;
|
||||||
|
struct mie_dialect *tr_parent;
|
||||||
|
enum mie_trait_flags tr_flags;
|
||||||
|
/* compatible target bitmask */
|
||||||
|
enum mie_trait_target_type tr_target;
|
||||||
|
|
||||||
|
/* the size of any corresponding struct mie_trait instances */
|
||||||
|
size_t tr_data_size;
|
||||||
|
|
||||||
|
void (*tr_init)(const struct mie_trait_definition *, struct mie_trait *);
|
||||||
|
enum mie_status (*tr_build_id)(
|
||||||
|
const struct mie_trait_definition *, const struct mie_trait *,
|
||||||
|
struct mie_id_builder *);
|
||||||
|
enum mie_status (*tr_print)(
|
||||||
|
const struct mie_trait_definition *, const struct mie_trait *,
|
||||||
|
b_stream *);
|
||||||
|
enum mie_status (*tr_cleanup)(
|
||||||
|
const struct mie_trait_definition *, struct mie_trait *);
|
||||||
|
enum mie_status (*tr_validate)(
|
||||||
|
const struct mie_trait_definition *, const struct mie_trait *,
|
||||||
|
const struct mie_trait_target *);
|
||||||
|
};
|
||||||
|
|
||||||
|
MIE_API struct mie_trait_definition *mie_trait_definition_create(
|
||||||
|
struct mie_dialect *parent, const char *name);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -15,6 +15,9 @@ struct mie_trait_table {
|
|||||||
|
|
||||||
struct mie_trait_table_iterator {
|
struct mie_trait_table_iterator {
|
||||||
const struct mie_trait *it_trait;
|
const struct mie_trait *it_trait;
|
||||||
|
int _f;
|
||||||
|
struct mie_id_map_iterator _n;
|
||||||
|
const struct mie_trait_table *_m;
|
||||||
b_queue_entry *_e;
|
b_queue_entry *_e;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -32,6 +35,9 @@ MIE_API enum mie_status mie_trait_table_get_generic(
|
|||||||
const char *trait_name, struct mie_trait_table_iterator *it);
|
const char *trait_name, struct mie_trait_table_iterator *it);
|
||||||
MIE_API enum mie_status mie_trait_table_put(
|
MIE_API enum mie_status mie_trait_table_put(
|
||||||
struct mie_trait_table *table, const struct mie_trait *trait);
|
struct mie_trait_table *table, const struct mie_trait *trait);
|
||||||
|
MIE_API enum mie_status mie_trait_table_iterate(
|
||||||
|
const struct mie_trait_table *table,
|
||||||
|
int (*func)(const struct mie_trait *, void *), void *arg);
|
||||||
|
|
||||||
MIE_API enum mie_status mie_trait_table_iterator_move_next(
|
MIE_API enum mie_status mie_trait_table_iterator_move_next(
|
||||||
struct mie_trait_table_iterator *it);
|
struct mie_trait_table_iterator *it);
|
||||||
|
|||||||
@@ -3,62 +3,18 @@
|
|||||||
|
|
||||||
#include <mie/id.h>
|
#include <mie/id.h>
|
||||||
|
|
||||||
struct mie_trait;
|
struct mie_dialect;
|
||||||
|
struct mie_trait_definition;
|
||||||
enum mie_trait_flags {
|
|
||||||
/* a trait user can only apply the trait once. this is assumed to be the
|
|
||||||
* case unless a trait is parametised, in which case this flag can be
|
|
||||||
* used to prevent more than one specialisation from being used. */
|
|
||||||
MIE_TRAIT_F_UNIQUE = 0x01u,
|
|
||||||
MIE_TRAIT_F_PARAMETISED = 0x02u,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* describe exactly which objects a trait can be applied to */
|
|
||||||
enum mie_trait_target_type {
|
|
||||||
MIE_TRAIT_TARGET_NONE = 0x00u,
|
|
||||||
MIE_TRAIT_TARGET_OP = 0x01u,
|
|
||||||
MIE_TRAIT_TARGET_TYPE = 0x02u,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct mie_trait_target {
|
|
||||||
enum mie_trait_target_type target_type;
|
|
||||||
union {
|
|
||||||
const struct mie_type *ptr_type;
|
|
||||||
const struct mie_op *ptr_op;
|
|
||||||
} target_ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* used to define a trait */
|
|
||||||
struct mie_trait_definition {
|
|
||||||
/* ID for the generic trait */
|
|
||||||
mie_id tr_id;
|
|
||||||
char *tr_name;
|
|
||||||
enum mie_trait_flags tr_flags;
|
|
||||||
/* compatible target bitmask */
|
|
||||||
enum mie_trait_target_type tr_target;
|
|
||||||
|
|
||||||
/* the size of any corresponding struct mie_trait instances */
|
|
||||||
size_t tr_data_size;
|
|
||||||
|
|
||||||
enum mie_status (*tr_build_id)(
|
|
||||||
const struct mie_trait_definition *, const struct mie_trait *,
|
|
||||||
struct mie_id_builder *);
|
|
||||||
enum mie_status (*tr_print)(
|
|
||||||
const struct mie_trait_definition *, const struct mie_trait *,
|
|
||||||
b_stream *);
|
|
||||||
enum mie_status (*tr_cleanup)(
|
|
||||||
const struct mie_trait_definition *, struct mie_trait *);
|
|
||||||
enum mie_status (*tr_validate)(
|
|
||||||
const struct mie_trait_definition *, const struct mie_trait *,
|
|
||||||
const struct mie_trait_target *);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* used to link an op/type/etc to a trait. if the trait is parametised, this
|
/* used to link an op/type/etc to a trait. if the trait is parametised, this
|
||||||
* struct includes any parameter values. */
|
* struct includes any parameter values. */
|
||||||
struct mie_trait {
|
struct mie_trait {
|
||||||
/* this is NOT the same as tr_def->tr_id */
|
/* this is NOT the same as tr_def->tr_id */
|
||||||
mie_id tr_id;
|
mie_id tr_id;
|
||||||
|
char *tr_name;
|
||||||
const struct mie_trait_definition *tr_def;
|
const struct mie_trait_definition *tr_def;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MIE_API void mie_trait_print(const struct mie_trait *type, b_stream *out);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -33,4 +33,7 @@ struct mie_type_definition {
|
|||||||
MIE_API struct mie_type_definition *mie_type_definition_create(
|
MIE_API struct mie_type_definition *mie_type_definition_create(
|
||||||
struct mie_dialect *parent, const char *name);
|
struct mie_dialect *parent, const char *name);
|
||||||
|
|
||||||
|
MIE_API enum mie_status mie_type_definition_add_trait(
|
||||||
|
struct mie_type_definition *type, const struct mie_trait *trait);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -17,9 +17,16 @@ struct mie_op_definition *mie_op_definition_create(
|
|||||||
}
|
}
|
||||||
|
|
||||||
out->op_parent = parent;
|
out->op_parent = parent;
|
||||||
|
mie_trait_table_init(&out->op_traits);
|
||||||
|
|
||||||
b_rope name_rope = B_ROPE_CSTR(name);
|
b_rope name_rope = B_ROPE_CSTR(name);
|
||||||
mie_id_map_put(&parent->d_ops, &out->op_id, &name_rope);
|
mie_id_map_put(&parent->d_ops, &out->op_id, &name_rope);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum mie_status mie_op_definition_add_trait(
|
||||||
|
struct mie_op_definition *op, const struct mie_trait *trait)
|
||||||
|
{
|
||||||
|
return mie_trait_table_put(&op->op_traits, trait);
|
||||||
|
}
|
||||||
|
|||||||
25
mie/trait/trait-definition.c
Normal file
25
mie/trait/trait-definition.c
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#include <blue/ds/string.h>
|
||||||
|
#include <mie/dialect/dialect.h>
|
||||||
|
#include <mie/trait/trait-definition.h>
|
||||||
|
|
||||||
|
struct mie_trait_definition *mie_trait_definition_create(
|
||||||
|
struct mie_dialect *parent, const char *name)
|
||||||
|
{
|
||||||
|
struct mie_trait_definition *out = malloc(sizeof *out);
|
||||||
|
if (!out) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
out->tr_name = b_strdup(name);
|
||||||
|
if (!out->tr_name) {
|
||||||
|
free(out);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
out->tr_parent = parent;
|
||||||
|
|
||||||
|
b_rope name_rope = B_ROPE_CSTR(name);
|
||||||
|
mie_id_map_put(&parent->d_traits, &out->tr_id, &name_rope);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#include <mie/dialect/dialect.h>
|
||||||
|
#include <mie/trait/trait-definition.h>
|
||||||
#include <mie/trait/trait-table.h>
|
#include <mie/trait/trait-table.h>
|
||||||
#include <mie/trait/trait.h>
|
#include <mie/trait/trait.h>
|
||||||
|
|
||||||
@@ -29,7 +31,6 @@ static struct unique_trait *unique_trait_create(const struct mie_trait *trait)
|
|||||||
}
|
}
|
||||||
|
|
||||||
memset(out, 0x0, sizeof *out);
|
memset(out, 0x0, sizeof *out);
|
||||||
out->u_id = trait->tr_id;
|
|
||||||
out->u_trait = trait;
|
out->u_trait = trait;
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
@@ -48,7 +49,6 @@ static struct generic_trait *generic_trait_create(const struct mie_trait *trait)
|
|||||||
}
|
}
|
||||||
|
|
||||||
memset(out, 0x0, sizeof *out);
|
memset(out, 0x0, sizeof *out);
|
||||||
out->g_id = trait->tr_def->tr_id;
|
|
||||||
|
|
||||||
struct unique_trait *entry = unique_trait_create(trait);
|
struct unique_trait *entry = unique_trait_create(trait);
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
@@ -113,12 +113,55 @@ const struct mie_trait *mie_trait_table_get_unique(
|
|||||||
static enum mie_status put_unique_trait(
|
static enum mie_status put_unique_trait(
|
||||||
struct mie_trait_table *table, const struct mie_trait *trait)
|
struct mie_trait_table *table, const struct mie_trait *trait)
|
||||||
{
|
{
|
||||||
|
struct unique_trait *unique = unique_trait_create(trait);
|
||||||
|
if (!unique) {
|
||||||
|
return MIE_ERR_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_id_builder id_ctx;
|
||||||
|
mie_id_builder_begin(&id_ctx, mie_id_map_get_ns(&table->tr_unique));
|
||||||
|
mie_id_builder_add_cstr(&id_ctx, trait->tr_def->tr_parent->d_name);
|
||||||
|
mie_id_builder_add_char(&id_ctx, '.');
|
||||||
|
mie_id_builder_add_cstr(&id_ctx, trait->tr_def->tr_name);
|
||||||
|
mie_id_builder_end(&id_ctx, &unique->u_id);
|
||||||
|
|
||||||
|
mie_id_map_put_id(&table->tr_unique, &unique->u_id);
|
||||||
|
|
||||||
return MIE_SUCCESS;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum mie_status put_generic_trait(
|
static enum mie_status put_generic_trait(
|
||||||
struct mie_trait_table *table, const struct mie_trait *trait)
|
struct mie_trait_table *table, const struct mie_trait *trait)
|
||||||
{
|
{
|
||||||
|
mie_id id;
|
||||||
|
struct mie_id_builder id_ctx;
|
||||||
|
mie_id_builder_begin(&id_ctx, mie_id_map_get_ns(&table->tr_generic));
|
||||||
|
mie_id_builder_add_cstr(&id_ctx, trait->tr_def->tr_parent->d_name);
|
||||||
|
mie_id_builder_add_char(&id_ctx, '.');
|
||||||
|
mie_id_builder_add_cstr(&id_ctx, trait->tr_def->tr_name);
|
||||||
|
mie_id_builder_end(&id_ctx, &id);
|
||||||
|
|
||||||
|
mie_id *target = mie_id_map_get(&table->tr_generic, &id);
|
||||||
|
struct generic_trait *generic
|
||||||
|
= b_unbox(struct generic_trait, target, g_id);
|
||||||
|
if (!generic) {
|
||||||
|
generic = generic_trait_create(trait);
|
||||||
|
|
||||||
|
if (!generic) {
|
||||||
|
return MIE_ERR_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
generic->g_id = id;
|
||||||
|
mie_id_map_put_id(&table->tr_generic, &generic->g_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct unique_trait *unique = unique_trait_create(trait);
|
||||||
|
if (!unique) {
|
||||||
|
return MIE_ERR_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_queue_push_back(&generic->g_traits, &unique->u_id.e_entry);
|
||||||
|
|
||||||
return MIE_SUCCESS;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,6 +206,51 @@ enum mie_status mie_trait_table_get_generic(
|
|||||||
return MIE_SUCCESS;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum mie_status mie_trait_table_iterate(
|
||||||
|
const struct mie_trait_table *table,
|
||||||
|
int (*func)(const struct mie_trait *, void *), void *arg)
|
||||||
|
{
|
||||||
|
struct mie_id_map_iterator it = {0};
|
||||||
|
mie_id_map_iterator_begin(&it, &table->tr_unique);
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
while (it.it_id) {
|
||||||
|
const struct unique_trait *trait
|
||||||
|
= b_unbox(struct unique_trait, it.it_id, u_id);
|
||||||
|
ret = func(trait->u_trait, arg);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_id_map_iterator_move_next(&it);
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_id_map_iterator_begin(&it, &table->tr_generic);
|
||||||
|
|
||||||
|
while (it.it_id) {
|
||||||
|
const struct generic_trait *trait_group
|
||||||
|
= b_unbox(struct generic_trait, it.it_id, g_id);
|
||||||
|
|
||||||
|
const b_queue_entry *cur = b_queue_first(&trait_group->g_traits);
|
||||||
|
while (cur) {
|
||||||
|
const struct unique_trait *trait
|
||||||
|
= b_unbox(struct unique_trait, cur, u_id.e_entry);
|
||||||
|
ret = func(trait->u_trait, arg);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur = b_queue_next(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_id_map_iterator_move_next(&it);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
enum mie_status mie_trait_table_iterator_move_next(
|
enum mie_status mie_trait_table_iterator_move_next(
|
||||||
struct mie_trait_table_iterator *it)
|
struct mie_trait_table_iterator *it)
|
||||||
{
|
{
|
||||||
|
|||||||
15
mie/trait/trait.c
Normal file
15
mie/trait/trait.c
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#include <mie/trait/trait-definition.h>
|
||||||
|
#include <mie/trait/trait.h>
|
||||||
|
|
||||||
|
void mie_trait_print(const struct mie_trait *trait, b_stream *out)
|
||||||
|
{
|
||||||
|
if (trait->tr_name) {
|
||||||
|
b_stream_write_string(out, trait->tr_name, NULL);
|
||||||
|
} else if (trait->tr_def && trait->tr_def->tr_print) {
|
||||||
|
trait->tr_def->tr_print(trait->tr_def, trait, out);
|
||||||
|
} else if (trait->tr_def->tr_name) {
|
||||||
|
b_stream_write_string(out, trait->tr_def->tr_name, NULL);
|
||||||
|
} else {
|
||||||
|
b_stream_write_string(out, "<UNNAMED-TRAIT>", NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,9 +17,16 @@ struct mie_type_definition *mie_type_definition_create(
|
|||||||
}
|
}
|
||||||
|
|
||||||
out->ty_parent = parent;
|
out->ty_parent = parent;
|
||||||
|
mie_trait_table_init(&out->ty_traits);
|
||||||
|
|
||||||
b_rope name_rope = B_ROPE_CSTR(name);
|
b_rope name_rope = B_ROPE_CSTR(name);
|
||||||
mie_id_map_put(&parent->d_types, &out->ty_id, &name_rope);
|
mie_id_map_put(&parent->d_types, &out->ty_id, &name_rope);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum mie_status mie_type_definition_add_trait(
|
||||||
|
struct mie_type_definition *type, const struct mie_trait *trait)
|
||||||
|
{
|
||||||
|
return mie_trait_table_put(&type->ty_traits, trait);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user