diff --git a/mie/ctx.c b/mie/ctx.c index f0ca476..2b489e8 100644 --- a/mie/ctx.c +++ b/mie/ctx.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -185,6 +186,30 @@ const struct mie_attribute_definition *mie_ctx_get_attribute_definition( return b_unbox(struct mie_attribute_definition, target, a_id); } +const struct mie_interface_definition *mie_ctx_get_interface_definition( + const struct mie_ctx *ctx, const char *dialect_name, + const char *interface_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 interface_name_rope = B_ROPE_CSTR(interface_name); + mie_id_init_ns( + &id, mie_id_map_get_ns(&dialect->d_interfaces), + &interface_name_rope); + target = mie_id_map_get(&dialect->d_interfaces, &id); + + return b_unbox(struct mie_interface_definition, target, if_id); +} + struct mie_type *mie_ctx_get_type( struct mie_ctx *ctx, const char *dialect_name, const char *type_name) { diff --git a/mie/dialect/dialect.c b/mie/dialect/dialect.c index fbacad9..6c74a3b 100644 --- a/mie/dialect/dialect.c +++ b/mie/dialect/dialect.c @@ -19,6 +19,10 @@ MIE_ID(0x86, 0x76, 0xcb, 0xfb, 0xc8, 0xe5, 0x40, 0x7d, 0xa3, 0x84, \ 0x93, 0xe3, 0xa5, 0x29, 0x74, 0xfe) +#define INTERFACE_NS_ID \ + MIE_ID(0xc5, 0x85, 0x7f, 0x8a, 0x7d, 0xe4, 0x4d, 0x03, 0x88, 0x8d, \ + 0x34, 0x32, 0xbf, 0x29, 0x5c, 0x72) + struct mie_dialect *mie_dialect_create( struct mie_ctx *ctx, const char *name, size_t size) { @@ -51,6 +55,9 @@ struct mie_dialect *mie_dialect_create( mie_id attribute_ns = ATTRIBUTE_NS_ID; mie_id_map_init(&out->d_attributes, &attribute_ns); + mie_id interface_ns = INTERFACE_NS_ID; + mie_id_map_init(&out->d_interfaces, &interface_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/op/func.c b/mie/dialect/func/op/func.c index 5a9ca29..9ea79ed 100644 --- a/mie/dialect/func/op/func.c +++ b/mie/dialect/func/op/func.c @@ -1,4 +1,8 @@ +#include +#include #include +#include +#include #include #include @@ -15,4 +19,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out) MIE_OP_DEFINITION_BEGIN(mie_func_func, "func") MIE_OP_DEFINITION_PRINT(print); MIE_OP_DEFINITION_PARSE(parse); + MIE_OP_INTERFACE_BEGIN("builtin", "symbol", struct mie_symbol) + MIE_OP_INTERFACE_FUNC(sym_get_name) = NULL; + MIE_OP_INTERFACE_END() MIE_OP_DEFINITION_END() diff --git a/mie/include/mie/ctx.h b/mie/include/mie/ctx.h index f92ee06..6474989 100644 --- a/mie/include/mie/ctx.h +++ b/mie/include/mie/ctx.h @@ -44,6 +44,9 @@ MIE_API const struct mie_trait_definition *mie_ctx_get_trait_definition( 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 const struct mie_interface_definition *mie_ctx_get_interface_definition( + const struct mie_ctx *ctx, const char *dialect_name, + const char *iface_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( diff --git a/mie/include/mie/dialect/dialect.h b/mie/include/mie/dialect/dialect.h index 3838351..5ab5932 100644 --- a/mie/include/mie/dialect/dialect.h +++ b/mie/include/mie/dialect/dialect.h @@ -25,6 +25,8 @@ struct mie_dialect { struct mie_id_map d_traits; /* map of struct mie_attribute_definition */ struct mie_id_map d_attributes; + /* map of struct mie_interface_definition */ + struct mie_id_map d_interfaces; enum mie_status (*d_cleanup)(struct mie_dialect *); }; @@ -40,5 +42,7 @@ 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); +MIE_API const struct mie_interface_definition *mie_dialect_get_interface( + const struct mie_dialect *dialect, const char *name); #endif diff --git a/mie/include/mie/interface/interface-definition.h b/mie/include/mie/interface/interface-definition.h new file mode 100644 index 0000000..c40551a --- /dev/null +++ b/mie/include/mie/interface/interface-definition.h @@ -0,0 +1,17 @@ +#ifndef MIE_INTERFACE_INTERFACE_DEFINITION_H_ +#define MIE_INTERFACE_INTERFACE_DEFINITION_H_ + +#include +#include + +struct mie_interface_definition { + mie_id if_id; + const struct mie_dialect *if_parent; + char *if_name; + size_t if_size; +}; + +MIE_API struct mie_interface_definition *mie_interface_definition_create( + struct mie_dialect *parent, const char *name); + +#endif diff --git a/mie/include/mie/interface/interface-map.h b/mie/include/mie/interface/interface-map.h new file mode 100644 index 0000000..26c7918 --- /dev/null +++ b/mie/include/mie/interface/interface-map.h @@ -0,0 +1,22 @@ +#ifndef MIE_INTERFACE_INTERFACE_MAP_H_ +#define MIE_INTERFACE_INTERFACE_MAP_H_ + +#include +#include + +struct mie_interface; + +struct mie_interface_map { + struct mie_id_map m_entries; +}; + +MIE_API void mie_interface_map_init(struct mie_interface_map *map); +MIE_API void mie_interface_map_cleanup(struct mie_interface_map *map); + +MIE_API enum mie_status mie_interface_map_put( + struct mie_interface_map *map, struct mie_interface *iface); +MIE_API const struct mie_interface *mie_interface_map_get( + const struct mie_interface_map *map, const char *dialect, + const char *iface); + +#endif diff --git a/mie/include/mie/interface/interface.h b/mie/include/mie/interface/interface.h new file mode 100644 index 0000000..d4bee55 --- /dev/null +++ b/mie/include/mie/interface/interface.h @@ -0,0 +1,19 @@ +#ifndef MIE_INTERFACE_INTERFACE_H_ +#define MIE_INTERFACE_INTERFACE_H_ + +#include +#include + +struct mie_dialect; +struct mie_interface_definition; + +struct mie_interface { + mie_id if_id; + const struct mie_interface_definition *if_def; +}; + +MIE_API struct mie_interface *mie_interface_create( + const struct mie_interface_definition *def); +MIE_API void mie_interface_destroy(struct mie_interface *iface); + +#endif diff --git a/mie/include/mie/ir/op-definition.h b/mie/include/mie/ir/op-definition.h index d00f9d2..6ee44b7 100644 --- a/mie/include/mie/ir/op-definition.h +++ b/mie/include/mie/ir/op-definition.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -96,6 +97,7 @@ struct mie_op_definition { char *op_name; struct mie_trait_table op_traits; + struct mie_interface_map op_iface; const struct mie_op_param op_params[MIE_OP_MAX_PARAMS]; const struct mie_op_result op_results[MIE_OP_MAX_RESULTS]; @@ -108,5 +110,7 @@ MIE_API struct mie_op_definition *mie_op_definition_create( MIE_API enum mie_status mie_op_definition_add_trait( struct mie_op_definition *op, const struct mie_trait *trait); +MIE_API enum mie_status mie_op_definition_add_interface( + struct mie_op_definition *op, struct mie_interface *inface); #endif diff --git a/mie/include/mie/macros.h b/mie/include/mie/macros.h index a15d5a2..b1df773 100644 --- a/mie/include/mie/macros.h +++ b/mie/include/mie/macros.h @@ -12,7 +12,8 @@ struct mie_op_definition *op = NULL; \ struct mie_type_definition *type = NULL; \ struct mie_trait_definition *trait = NULL; \ - struct mie_attribute_definition *attribute = NULL; + struct mie_attribute_definition *attribute = NULL; \ + struct mie_interface_definition *interface = NULL; #define __MIE_DIALECT_END() \ return self; \ @@ -27,7 +28,9 @@ if (!op) { \ return NULL; \ } \ - const struct mie_trait *trait = NULL; + const struct mie_trait *trait = NULL; \ + struct mie_interface *i = NULL; \ + const struct mie_interface_definition *id = NULL; #define __MIE_OP_DEFINITION_END() \ return op; \ @@ -76,6 +79,20 @@ return attribute; \ } +#define __MIE_INTERFACE_DEFINITION_BEGIN(func_prefix, iface_name) \ + struct mie_interface_definition *func_prefix##_interface_create( \ + struct mie_dialect *d, struct mie_ctx *ctx) \ + { \ + struct mie_interface_definition *i \ + = mie_interface_definition_create(d, iface_name); \ + if (!i) { \ + return NULL; \ + } + +#define __MIE_INTERFACE_DEFINITION_END() \ + return i; \ + } + #define __MIE_DIALECT_INIT(func) func(self) #define __MIE_DIALECT_CLEANUP(func) self->d_cleanup = (func) #define __MIE_DIALECT_ADD_OP(op_id) \ @@ -90,11 +107,14 @@ extern struct mie_trait_definition *trait_id##_trait_create( \ struct mie_dialect *, struct mie_ctx *); \ trait = trait_id##_trait_create(self, ctx) - #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_ADD_INTERFACE(interface_id) \ + extern struct mie_interface_definition *interface_id##_interface_create( \ + struct mie_dialect *, struct mie_ctx *); \ + interface = interface_id##_interface_create(self, ctx) #define MIE_DIALECT_BEGIN(c_sym, c_struct, name) \ __MIE_DIALECT_BEGIN(c_sym, c_struct, name) @@ -105,6 +125,7 @@ #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_DIALECT_ADD_INTERFACE(c_sym) __MIE_DIALECT_ADD_INTERFACE(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() @@ -113,6 +134,15 @@ #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_OP_INTERFACE_BEGIN(dialect_name, if_name, c_struct) \ + id = mie_ctx_get_interface_definition(ctx, dialect_name, if_name); \ + if (id) { \ + c_struct *iface = (c_struct *)mie_interface_create(id); +#define MIE_OP_INTERFACE_FUNC(func_name) iface->func_name + +#define MIE_OP_INTERFACE_END() \ + mie_op_definition_add_interface(op, (struct mie_interface *)iface); \ + } #define MIE_TYPE_DEFINITION_BEGIN(c_sym, type) \ __MIE_TYPE_DEFINITION_BEGIN(c_sym, type) @@ -149,4 +179,9 @@ #define MIE_ATTRIBUTE_DEFINITION_PRINT(func) attribute->a_print = (func) #define MIE_ATTRIBUTE_DEFINITION_PARSE(func) attribute->a_parse = (func) +#define MIE_INTERFACE_DEFINITION_BEGIN(c_sym, iface) \ + __MIE_INTERFACE_DEFINITION_BEGIN(c_sym, iface) +#define MIE_INTERFACE_DEFINITION_END() __MIE_INTERFACE_DEFINITION_END() +#define MIE_INTERFACE_DEFINITION_STRUCT(name) i->if_size = sizeof(name) + #endif diff --git a/mie/interface/interface-definition.c b/mie/interface/interface-definition.c new file mode 100644 index 0000000..f647de3 --- /dev/null +++ b/mie/interface/interface-definition.c @@ -0,0 +1,28 @@ +#include +#include +#include + +struct mie_interface_definition *mie_interface_definition_create( + struct mie_dialect *parent, const char *name) +{ + struct mie_interface_definition *out = malloc(sizeof *out); + if (!out) { + return NULL; + } + + memset(out, 0x0, sizeof *out); + + out->if_name = b_strdup(name); + if (!out->if_name) { + free(out); + return NULL; + } + + out->if_parent = parent; + out->if_size = 0; + + b_rope name_rope = B_ROPE_CSTR(name); + mie_id_map_put(&parent->d_interfaces, &out->if_id, &name_rope); + + return out; +} diff --git a/mie/interface/interface-map.c b/mie/interface/interface-map.c new file mode 100644 index 0000000..3f05a1f --- /dev/null +++ b/mie/interface/interface-map.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include + +#define INTERFACE_NS_ID \ + MIE_ID(0xd2, 0x40, 0x70, 0x93, 0x4b, 0x2b, 0x46, 0xb2, 0x96, 0x48, \ + 0x69, 0xe4, 0x0a, 0x0d, 0x70, 0x55) + +void mie_interface_map_init(struct mie_interface_map *map) +{ + memset(map, 0x0, sizeof *map); + + mie_id ns_id = INTERFACE_NS_ID; + mie_id_map_init(&map->m_entries, &ns_id); +} + +void mie_interface_map_cleanup(struct mie_interface_map *map) +{ + /* TODO */ +} + +enum mie_status mie_interface_map_put( + struct mie_interface_map *map, struct mie_interface *iface) +{ + struct mie_id_builder id_ctx; + mie_id_builder_begin(&id_ctx, mie_id_map_get_ns(&map->m_entries)); + mie_id_builder_add_cstr(&id_ctx, iface->if_def->if_parent->d_name); + mie_id_builder_add_char(&id_ctx, '.'); + mie_id_builder_add_cstr(&id_ctx, iface->if_def->if_name); + mie_id_builder_end(&id_ctx, &iface->if_id); + + mie_id_map_put_id(&map->m_entries, &iface->if_id); + + return MIE_SUCCESS; +} + +const struct mie_interface *mie_interface_map_get( + const struct mie_interface_map *map, const char *dialect_name, + const char *iface_name) +{ + mie_id id; + struct mie_id_builder id_ctx; + mie_id_builder_begin(&id_ctx, mie_id_map_get_ns(&map->m_entries)); + mie_id_builder_add_cstr(&id_ctx, dialect_name); + mie_id_builder_add_char(&id_ctx, '.'); + mie_id_builder_add_cstr(&id_ctx, iface_name); + mie_id_builder_end(&id_ctx, &id); + + const mie_id *result = mie_id_map_get(&map->m_entries, &id); + const struct mie_interface *iface + = b_unbox(const struct mie_interface, result, if_id); + return iface; +} diff --git a/mie/interface/interface.c b/mie/interface/interface.c new file mode 100644 index 0000000..82aeaae --- /dev/null +++ b/mie/interface/interface.c @@ -0,0 +1,26 @@ +#include +#include + +struct mie_interface *mie_interface_create( + const struct mie_interface_definition *def) +{ + if (def->if_size < sizeof(struct mie_interface)) { + return NULL; + } + + struct mie_interface *out = malloc(def->if_size); + if (!out) { + return NULL; + } + + memset(out, 0x0, def->if_size); + + out->if_def = def; + + return out; +} + +void mie_interface_destroy(struct mie_interface *iface) +{ + free(iface); +} diff --git a/mie/ir/op-definition.c b/mie/ir/op-definition.c index 285c832..a9fc34b 100644 --- a/mie/ir/op-definition.c +++ b/mie/ir/op-definition.c @@ -18,6 +18,7 @@ struct mie_op_definition *mie_op_definition_create( out->op_parent = parent; mie_trait_table_init(&out->op_traits); + mie_interface_map_init(&out->op_iface); b_rope name_rope = B_ROPE_CSTR(name); mie_id_map_put(&parent->d_ops, &out->op_id, &name_rope); @@ -30,3 +31,9 @@ enum mie_status mie_op_definition_add_trait( { return mie_trait_table_put(&op->op_traits, trait); } + +enum mie_status mie_op_definition_add_interface( + struct mie_op_definition *op, struct mie_interface *interface) +{ + return mie_interface_map_put(&op->op_iface, interface); +}