Compare commits

...

9 Commits

35 changed files with 1344 additions and 224 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>
@@ -325,7 +327,10 @@ 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)
{ {
if (op->op_flags & MIE_OP_F_RESOLVED) { bool fully_resolved = MIE_TEST_FLAGS(
op->op_flags, MIE_OP_F_OP_RESOLVED | MIE_OP_F_ARGS_RESOLVED);
if (fully_resolved) {
return true; return true;
} }
@@ -365,7 +370,7 @@ bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
free(op->op_name); free(op->op_name);
op->op_name = NULL; op->op_name = NULL;
op->op_flags |= MIE_OP_F_RESOLVED; op->op_flags |= MIE_OP_F_OP_RESOLVED;
return true; return true;
} }
@@ -419,7 +424,7 @@ struct mie_type *mie_ctx_get_type(
struct mie_dialect_type *type_info struct mie_dialect_type *type_info
= mie_ctx_get_dialect_type(ctx, dialect_name, type_name); = mie_ctx_get_dialect_type(ctx, dialect_name, type_name);
if (!type_info || (type_info->ty_flags & MIE_DIALECT_TYPE_PARAMETISED)) { if (!type_info /* || (type_info->ty_flags & MIE_DIALECT_TYPE_PARAMETISED) */) {
/* cannot initialise unknown or parametised types */ /* cannot initialise unknown or parametised types */
return NULL; return NULL;
} }
@@ -448,6 +453,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

@@ -60,9 +60,8 @@ struct mie_type *mie_arith_float_get_type(struct mie_ctx *ctx, size_t bit_width)
} }
type->f_base.ty_name = b_bstr_fmt("arith.float<%zu>", bit_width); type->f_base.ty_name = b_bstr_fmt("arith.float<%zu>", bit_width);
type->f_width = bit_width;
type->f_base.ty_instance_size = sizeof(struct mie_float); type->f_base.ty_instance_size = sizeof(struct mie_float);
type->f_base.ty_value_print = value_print; type->f_width = bit_width;
mie_id_map_put(&ctx->ctx_types, &type->f_base.ty_id, &type_name); mie_id_map_put(&ctx->ctx_types, &type->f_base.ty_id, &type_name);
return (struct mie_type *)type; return (struct mie_type *)type;
@@ -82,8 +81,9 @@ static enum mie_status parse(
} }
MIE_DIALECT_TYPE_BEGIN(mie_arith_float, "float") MIE_DIALECT_TYPE_BEGIN(mie_arith_float, "float")
MIE_DIALECT_TYPE_FLAGS(MIE_DIALECT_TYPE_PARAMETISED); // MIE_DIALECT_TYPE_FLAGS(MIE_DIALECT_TYPE_PARAMETISED);
MIE_DIALECT_TYPE_STRUCT(struct float_type); MIE_DIALECT_TYPE_STRUCT(struct float_type);
MIE_DIALECT_TYPE_PRINT(print); MIE_DIALECT_TYPE_PRINT(print);
MIE_DIALECT_TYPE_PARSE(parse); MIE_DIALECT_TYPE_PARSE(parse);
MIE_DIALECT_TYPE_VALUE_PRINT(value_print);
MIE_DIALECT_TYPE_END() MIE_DIALECT_TYPE_END()

View File

@@ -52,9 +52,8 @@ struct mie_type *mie_arith_int_get_type(struct mie_ctx *ctx, size_t bit_width)
} }
type->i_base.ty_name = b_bstr_fmt("arith.int<%zu>", bit_width); type->i_base.ty_name = b_bstr_fmt("arith.int<%zu>", bit_width);
type->i_width = bit_width;
type->i_base.ty_instance_size = sizeof(struct mie_int); type->i_base.ty_instance_size = sizeof(struct mie_int);
type->i_base.ty_value_print = value_print; type->i_width = bit_width;
mie_id_map_put(&ctx->ctx_types, &type->i_base.ty_id, &type_name); mie_id_map_put(&ctx->ctx_types, &type->i_base.ty_id, &type_name);
return (struct mie_type *)type; return (struct mie_type *)type;
@@ -74,8 +73,9 @@ static enum mie_status parse(
} }
MIE_DIALECT_TYPE_BEGIN(mie_arith_int, "int") MIE_DIALECT_TYPE_BEGIN(mie_arith_int, "int")
MIE_DIALECT_TYPE_FLAGS(MIE_DIALECT_TYPE_PARAMETISED); // MIE_DIALECT_TYPE_FLAGS(MIE_DIALECT_TYPE_PARAMETISED);
MIE_DIALECT_TYPE_STRUCT(struct int_type); MIE_DIALECT_TYPE_STRUCT(struct int_type);
MIE_DIALECT_TYPE_PRINT(print); MIE_DIALECT_TYPE_PRINT(print);
MIE_DIALECT_TYPE_PARSE(parse); MIE_DIALECT_TYPE_PARSE(parse);
MIE_DIALECT_TYPE_VALUE_PRINT(value_print);
MIE_DIALECT_TYPE_END() MIE_DIALECT_TYPE_END()

View File

@@ -17,7 +17,6 @@ static void value_print(
static void type_init(const struct mie_dialect_type *type_info, struct mie_type *type) static void type_init(const struct mie_dialect_type *type_info, struct mie_type *type)
{ {
type->ty_instance_size = sizeof(struct mie_string); type->ty_instance_size = sizeof(struct mie_string);
type->ty_value_print = value_print;
} }
static enum mie_status print( static enum mie_status print(
@@ -38,4 +37,5 @@ MIE_DIALECT_TYPE_BEGIN(mie_builtin_string, "string")
MIE_DIALECT_TYPE_INIT(type_init); MIE_DIALECT_TYPE_INIT(type_init);
MIE_DIALECT_TYPE_PRINT(print); MIE_DIALECT_TYPE_PRINT(print);
MIE_DIALECT_TYPE_PARSE(parse); MIE_DIALECT_TYPE_PARSE(parse);
MIE_DIALECT_TYPE_VALUE_PRINT(value_print);
MIE_DIALECT_TYPE_END() MIE_DIALECT_TYPE_END()

View File

@@ -22,7 +22,6 @@ static void value_print(
static void type_init(const struct mie_dialect_type *type_info, struct mie_type *type) static void type_init(const struct mie_dialect_type *type_info, struct mie_type *type)
{ {
type->ty_instance_size = sizeof(struct mie_index); type->ty_instance_size = sizeof(struct mie_index);
type->ty_value_print = value_print;
} }
static enum mie_status print( static enum mie_status print(
@@ -43,6 +42,7 @@ MIE_DIALECT_TYPE_BEGIN(mie_index_index, "index")
MIE_DIALECT_TYPE_INIT(type_init); MIE_DIALECT_TYPE_INIT(type_init);
MIE_DIALECT_TYPE_PRINT(print); MIE_DIALECT_TYPE_PRINT(print);
MIE_DIALECT_TYPE_PARSE(parse); MIE_DIALECT_TYPE_PARSE(parse);
MIE_DIALECT_TYPE_VALUE_PRINT(value_print);
MIE_DIALECT_TYPE_END() MIE_DIALECT_TYPE_END()
MIE_DIALECT_BEGIN(mie_index, "index") MIE_DIALECT_BEGIN(mie_index, "index")

View File

@@ -99,19 +99,10 @@ void mie_id_init_random(mie_id *out)
void mie_id_init_ns(mie_id *out, const mie_id *ns, const b_rope *name) void mie_id_init_ns(mie_id *out, const mie_id *ns, const b_rope *name)
{ {
b_hash_ctx hash; struct mie_id_builder ctx;
b_hash_ctx_init(&hash, B_HASH_SHA1); mie_id_builder_begin(&ctx, ns);
mie_id_builder_add_rope(&ctx, name);
b_hash_ctx_update(&hash, ns->id_bytes, sizeof ns->id_bytes); mie_id_builder_end(&ctx, out);
b_hash_ctx_update_rope(&hash, name);
b_hash_ctx_finish(&hash, out->id_bytes, sizeof out->id_bytes);
out->id_bytes[6] &= 0x0F;
out->id_bytes[6] |= 0x50;
out->id_bytes[8] &= 0x3F;
out->id_bytes[8] |= 0x80;
} }
void mie_id_to_string(const mie_id *id, char *out, size_t max) void mie_id_to_string(const mie_id *id, char *out, size_t max)
@@ -145,7 +136,48 @@ void mie_id_map_put(struct mie_id_map *map, mie_id *id, const b_rope *name)
put_id(&map->map_entries, id); put_id(&map->map_entries, id);
} }
void mie_id_map_put_id(struct mie_id_map *map, mie_id *node)
{
put_id(&map->map_entries, node);
}
mie_id *mie_id_map_get(const struct mie_id_map *map, mie_id *id) mie_id *mie_id_map_get(const struct mie_id_map *map, mie_id *id)
{ {
return get_id(&map->map_entries, id); return get_id(&map->map_entries, id);
} }
void mie_id_builder_begin(struct mie_id_builder *builder, const mie_id *ns)
{
memset(builder, 0x0, sizeof *builder);
b_hash_ctx_init(&builder->b_hash, B_HASH_SHA1);
b_hash_ctx_update(&builder->b_hash, ns->id_bytes, sizeof ns->id_bytes);
}
void mie_id_builder_add(struct mie_id_builder *builder, const void *p, size_t len)
{
b_hash_ctx_update(&builder->b_hash, p, len);
}
void mie_id_builder_add_rope(struct mie_id_builder *builder, const b_rope *rope)
{
b_hash_ctx_update_rope(&builder->b_hash, rope);
}
void mie_id_builder_add_marker(
struct mie_id_builder *builder, enum mie_id_builder_marker marker)
{
unsigned char c = marker;
b_hash_ctx_update(&builder->b_hash, &c, sizeof c);
}
void mie_id_builder_end(struct mie_id_builder *builder, mie_id *out)
{
memset(out, 0x0, sizeof *out);
b_hash_ctx_finish(&builder->b_hash, out->id_bytes, sizeof out->id_bytes);
out->id_bytes[6] &= 0x0F;
out->id_bytes[6] |= 0x50;
out->id_bytes[8] &= 0x3F;
out->id_bytes[8] |= 0x80;
}

View File

@@ -19,8 +19,12 @@ struct mie_ctx {
b_hashmap *ctx_sel_cache; b_hashmap *ctx_sel_cache;
b_hashmap *ctx_string_cache; b_hashmap *ctx_string_cache;
#endif #endif
/* map of struct mie_dialect */
struct mie_id_map ctx_dialects; struct mie_id_map ctx_dialects;
/* map of struct mie_type */
struct mie_id_map ctx_types; struct mie_id_map ctx_types;
/* map of struct mie_trait */
struct mie_id_map ctx_traits;
struct mie_int_cache *ctx_ints; struct mie_int_cache *ctx_ints;
struct mie_index_cache *ctx_indices; struct mie_index_cache *ctx_indices;
@@ -38,6 +42,13 @@ 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_trait(
struct mie_ctx *ctx, const char *dialect_name, const char *trait_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

@@ -11,13 +11,18 @@ struct mie_ctx;
struct mie_dialect_op; struct mie_dialect_op;
struct mie_dialect_type; struct mie_dialect_type;
struct mie_trait_definition;
struct mie_dialect { struct mie_dialect {
mie_id d_id; mie_id d_id;
char *d_name; char *d_name;
/* map of struct mie_dialect_op */
struct mie_id_map d_ops; struct mie_id_map d_ops;
/* map of struct mie_dialect_type */
struct mie_id_map d_types; struct mie_id_map d_types;
/* map of struct mie_trait_definition */
struct mie_id_map d_traits;
}; };
MIE_API struct mie_dialect *mie_dialect_create( MIE_API struct mie_dialect *mie_dialect_create(
@@ -27,5 +32,7 @@ MIE_API const struct mie_dialect_op *mie_dialect_get_op(
const struct mie_dialect *dialect, const char *name); const struct mie_dialect *dialect, const char *name);
MIE_API const struct mie_dialect_type *mie_dialect_get_type( MIE_API const struct mie_dialect_type *mie_dialect_get_type(
const struct mie_dialect *dialect, const char *name); const struct mie_dialect *dialect, const char *name);
MIE_API const struct mie_trait_definition *mie_dialect_get_trait(
const struct mie_dialect *dialect, const char *name);
#endif #endif

View File

@@ -5,16 +5,98 @@
#include <blue/core/stream.h> #include <blue/core/stream.h>
#include <mie/id.h> #include <mie/id.h>
#include <mie/status.h> #include <mie/status.h>
#include <mie/trait/trait-table.h>
#define MIE_OP_MAX_PARAMS 8
#define MIE_OP_MAX_RESULTS 8
struct mie_op; struct mie_op;
struct mie_parser; struct mie_parser;
struct mie_dialect; struct mie_dialect;
enum mie_op_trait {
MIE_OP_TRAIT_NONE = 0x00u,
/* this is a graph op. references to it by name must be prefixed with +
* and the op can only be used within graph regions.
* a graph op can have the same name as a regular or non-graph op. */
MIE_OP_TRAIT_GRAPH_ONLY = 0x01u,
/* this is a non-graph op. this op cannot be used within graph regions */
MIE_OP_TRAIT_NO_GRAPH = 0x02u,
/* regions of an op that has this trait are graph regions. graph regions
* cannot have more than one block, and the entry block must be unnamed
* with no parameters. However, graph ops can be used. */
MIE_OP_TRAIT_GRAPH_SCOPE = 0x04u,
/* regions of an op that has this trait cannot capture or reference
* values defined in the enclosing scope. */
MIE_OP_TRAIT_ISOLATED_FROM_ABOVE = 0x08u,
};
enum mie_op_param_type {
/* op has no parameter */
MIE_OP_PARTYPE_NONE = 0,
/* op has a parameter of any type. */
MIE_OP_PARTYPE_ANY,
/* op has a parameter of a fixed, named type. */
MIE_OP_PARTYPE_TYPE_NAME,
/* op has a parameter whose type matches the type of an attribute value */
MIE_OP_PARTYPE_ATTRIB_VAL,
};
enum mie_op_result_type {
/* op has no result */
MIE_OP_RESTYPE_NONE = 0,
/* op has a result of any type. */
MIE_OP_RESTYPE_ANY,
/* op has a result of a fixed, named type. */
MIE_OP_RESTYPE_TYPE_NAME,
/* op has a result whose type matches the type of an input parameter */
MIE_OP_RESTYPE_IN_VAL,
/* op has a result whose type matches the type of an attribute value */
MIE_OP_RESTYPE_ATTRIB_VAL,
};
struct mie_op_param {
enum mie_op_param_type param_type;
union {
struct {
const char *t_dialect;
/* this can be NULL, in which case any type from the
* dialect named in t_dialect will be accepted. */
const char *t_name;
} param_type_name;
const char *param_attrib;
};
};
struct mie_op_result {
enum mie_op_result_type r_type;
union {
struct {
const char *t_dialect;
const char *t_name;
} r_type_name;
unsigned int r_in_index;
const char *r_attrib;
};
};
struct mie_dialect_op { struct mie_dialect_op {
mie_id op_id; mie_id op_id;
struct mie_dialect *op_parent; struct mie_dialect *op_parent;
char *op_name; char *op_name;
struct mie_trait_table op_traits;
const struct mie_op_param op_params[MIE_OP_MAX_PARAMS];
const struct mie_op_result op_results[MIE_OP_MAX_RESULTS];
enum mie_status (*op_print)(const struct mie_op *, b_stream *); enum mie_status (*op_print)(const struct mie_op *, b_stream *);
enum mie_status (*op_parse)(struct mie_parser *, struct mie_op *); enum mie_status (*op_parse)(struct mie_parser *, struct mie_op *);
}; };

View File

@@ -5,31 +5,45 @@
#include <blue/core/stream.h> #include <blue/core/stream.h>
#include <mie/id.h> #include <mie/id.h>
#include <mie/status.h> #include <mie/status.h>
#include <mie/trait/trait-table.h>
struct mie_type; struct mie_type;
struct mie_value;
struct mie_parser; struct mie_parser;
struct mie_dialect; struct mie_dialect;
enum mie_dialect_type_flags { enum mie_type_trait {
MIE_DIALECT_TYPE_PARAMETISED = 0x01u, /* this type is parametised. one or more arguments are required to create
* a corresponding mie_type instance. in textual IR, references to this
* type will be followed by a set of arguments surrounded
* by <angle brackets>. */
MIE_TYPE_TRAIT_PARAMETISED = 0x01u,
/* this type can only be used within graph regions. unlike graph ops,
* no special prefix is required */
MIE_TYPE_TRAIT_GRAPH_TYPE = 0x02u,
}; };
struct mie_dialect_type { struct mie_dialect_type {
mie_id ty_id; mie_id ty_id;
enum mie_dialect_type_flags ty_flags; struct mie_trait_table ty_traits;
struct mie_dialect *ty_parent; struct mie_dialect *ty_parent;
char *ty_name; char *ty_name;
size_t ty_data_size; size_t ty_data_size;
void (*ty_init)(const struct mie_dialect_type *, struct mie_type *);
void (*ty_cleanup)(const struct mie_dialect_type *, struct mie_type *);
void (*ty_instance_cleanup)(const struct mie_type *, struct mie_value *);
enum mie_status (*ty_print)( enum mie_status (*ty_print)(
const struct mie_dialect_type *, const struct mie_type *, const struct mie_dialect_type *, const struct mie_type *,
b_stream *); b_stream *);
void (*ty_value_print)(
const struct mie_type *, const struct mie_value *, b_stream *);
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

@@ -22,6 +22,15 @@
#define MIE_ID_NR_WORDS_32 (MIE_ID_NR_BYTES / sizeof(uint32_t)) #define MIE_ID_NR_WORDS_32 (MIE_ID_NR_BYTES / sizeof(uint32_t))
#define MIE_ID_NR_WORDS_64 (MIE_ID_NR_BYTES / sizeof(uint64_t)) #define MIE_ID_NR_WORDS_64 (MIE_ID_NR_BYTES / sizeof(uint64_t))
enum mie_id_builder_marker {
MIE_ID_BUILDER_STORAGE_START = 0x32,
MIE_ID_BUILDER_STORAGE_END = 0x8a,
MIE_ID_BUILDER_FUNCTION_IN_START = 0x78,
MIE_ID_BUILDER_FUNCTION_IN_END = 0x55,
MIE_ID_BUILDER_FUNCTION_OUT_START = 0xa2,
MIE_ID_BUILDER_FUNCTION_OUT_END = 0xbc,
};
typedef struct mie_id { typedef struct mie_id {
union { union {
uint8_t id_bytes[MIE_ID_NR_BYTES]; uint8_t id_bytes[MIE_ID_NR_BYTES];
@@ -31,9 +40,16 @@ typedef struct mie_id {
uint64_t id_words_64[MIE_ID_NR_WORDS_64]; uint64_t id_words_64[MIE_ID_NR_WORDS_64];
}; };
union {
b_btree_node e_node; b_btree_node e_node;
b_queue_entry e_entry;
};
} mie_id; } mie_id;
struct mie_id_builder {
b_hash_ctx b_hash;
};
struct mie_id_map { struct mie_id_map {
mie_id map_ns_id; mie_id map_ns_id;
b_btree map_entries; b_btree map_entries;
@@ -54,7 +70,27 @@ MIE_API void mie_id_to_string(const mie_id *id, char *out, size_t max);
MIE_API void mie_id_map_init(struct mie_id_map *map, const mie_id *ns); MIE_API void mie_id_map_init(struct mie_id_map *map, const mie_id *ns);
MIE_API const mie_id *mie_id_map_get_ns(const struct mie_id_map *map); MIE_API const mie_id *mie_id_map_get_ns(const struct mie_id_map *map);
MIE_API void mie_id_map_put(struct mie_id_map *map, mie_id *id, const b_rope *name); MIE_API void mie_id_map_put(
struct mie_id_map *map, mie_id *node, const b_rope *name);
MIE_API void mie_id_map_put_id(struct mie_id_map *map, mie_id *node);
MIE_API mie_id *mie_id_map_get(const struct mie_id_map *map, mie_id *id); MIE_API mie_id *mie_id_map_get(const struct mie_id_map *map, mie_id *id);
MIE_API void mie_id_builder_begin(struct mie_id_builder *builder, const mie_id *ns);
MIE_API void mie_id_builder_add(
struct mie_id_builder *builder, const void *p, size_t len);
static inline void mie_id_builder_add_char(struct mie_id_builder *builder, char c)
{
mie_id_builder_add(builder, &c, 1);
}
static inline void mie_id_builder_add_cstr(
struct mie_id_builder *builder, const char *s)
{
mie_id_builder_add(builder, s, strlen(s));
}
MIE_API void mie_id_builder_add_rope(
struct mie_id_builder *builder, const b_rope *rope);
MIE_API void mie_id_builder_add_marker(
struct mie_id_builder *builder, enum mie_id_builder_marker marker);
MIE_API void mie_id_builder_end(struct mie_id_builder *builder, mie_id *out);
#endif #endif

View File

@@ -3,21 +3,23 @@
#include "mie/vector.h" #include "mie/vector.h"
#include <mie/ir/register.h>
#include <mie/misc.h> #include <mie/misc.h>
#include <mie/name.h> #include <mie/name.h>
#include <mie/parse/file-span.h>
struct mie_type; struct mie_type;
struct mie_value; struct mie_value;
struct mie_block; struct mie_block;
struct mie_region; struct mie_region;
struct mie_register;
struct mie_dialect; struct mie_dialect;
struct mie_dialect_op; struct mie_dialect_op;
enum mie_op_flags { enum mie_op_flags {
MIE_OP_F_RESOLVED = 0x01u, MIE_OP_F_OP_RESOLVED = 0x01u,
MIE_OP_F_ARGS_RESOLVED = 0x02u,
}; };
struct mie_op_successor { struct mie_op_successor {
@@ -30,6 +32,16 @@ struct mie_op_attribute {
struct mie_value *attrib_value; struct mie_value *attrib_value;
}; };
struct mie_op_arg {
struct mie_file_span arg_span;
union {
/* only valid if the parent op's F_ARGS_RESOLVED flag is set */
struct mie_register *arg_value;
/* only valid if the parent op's F_ARGS_RESOLVED flag is NOT set */
struct mie_register_ref arg_unresolved;
};
};
struct mie_op { struct mie_op {
enum mie_op_flags op_flags; enum mie_op_flags op_flags;
@@ -37,13 +49,14 @@ struct mie_op {
const struct mie_dialect *op_dialect; const struct mie_dialect *op_dialect;
const struct mie_dialect_op *op_info; const struct mie_dialect_op *op_info;
/* this pointer is only valid if the F_RESOLVED flag is NOT set */ struct mie_file_span op_name_span;
/* only valid if the F_RESOLVED flag is NOT set */
char *op_name; char *op_name;
MIE_VECTOR_DECLARE(struct mie_region, op_regions); MIE_VECTOR_DECLARE(struct mie_region, op_regions);
MIE_VECTOR_DECLARE(struct mie_op_successor, op_successors); MIE_VECTOR_DECLARE(struct mie_op_successor, op_successors);
MIE_VECTOR_DECLARE(struct mie_op_attribute, op_attrib); MIE_VECTOR_DECLARE(struct mie_op_attribute, op_attrib);
MIE_VECTOR_DECLARE(struct mie_register *, op_args); MIE_VECTOR_DECLARE(struct mie_op_arg, op_args);
MIE_VECTOR_DECLARE(struct mie_register, op_result); MIE_VECTOR_DECLARE(struct mie_register, op_result);
}; };

View File

@@ -11,16 +11,29 @@ enum mie_register_flags {
MIE_REGISTER_F_OP_PARAM = 0x02u, MIE_REGISTER_F_OP_PARAM = 0x02u,
MIE_REGISTER_F_BLOCK_PARAM = 0x04u, MIE_REGISTER_F_BLOCK_PARAM = 0x04u,
/* only ONE of these two flags can be set at a time */
MIE_REGISTER_F_VIRTUAL = 0x10u, MIE_REGISTER_F_VIRTUAL = 0x10u,
MIE_REGISTER_F_MACHINE = 0x20u, MIE_REGISTER_F_MACHINE = 0x20u,
}; };
/* represents a yet-to-be-resolved reference to a mie_register */
struct mie_register_ref {
enum mie_register_flags reg_flags;
char *reg_name;
/* what we THINK the type of the register is.
* if this is set, it gets checked during the register resolution process. */
const struct mie_type *reg_type;
};
struct mie_register { struct mie_register {
enum mie_register_flags reg_flags; enum mie_register_flags reg_flags;
union {
/* only valid if F_VIRTUAL is set. */
struct mie_name reg_name; struct mie_name reg_name;
/* only valid if F_MACHINE is set. */ /* only valid if F_MACHINE is set. */
struct mie_target_register *reg_mach; struct mie_target_register *reg_mach;
struct mie_type *reg_value_type; };
const struct mie_type *reg_type;
/* if this is an OP_RESULT register, this points to the block within /* if this is an OP_RESULT register, this points to the block within
* which this register is defined. * which this register is defined.
* if this is an OP_PARAM register, this pointer is NULL. * if this is an OP_PARAM register, this pointer is NULL.

View File

@@ -16,7 +16,8 @@
} }
#define __MIE_DIALECT_OP_BEGIN(func_prefix, op_name) \ #define __MIE_DIALECT_OP_BEGIN(func_prefix, op_name) \
struct mie_dialect_op *func_prefix##_op_create(struct mie_dialect *d) \ struct mie_dialect_op *func_prefix##_op_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \ { \
struct mie_dialect_op *op = mie_dialect_op_create(d, op_name); \ struct mie_dialect_op *op = mie_dialect_op_create(d, op_name); \
if (!op) { \ if (!op) { \
@@ -28,7 +29,8 @@
} }
#define __MIE_DIALECT_TYPE_BEGIN(func_prefix, type_name) \ #define __MIE_DIALECT_TYPE_BEGIN(func_prefix, type_name) \
struct mie_dialect_type *func_prefix##_type_create(struct mie_dialect *d) \ struct mie_dialect_type *func_prefix##_type_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \ { \
struct mie_dialect_type *type \ struct mie_dialect_type *type \
= mie_dialect_type_create(d, type_name); \ = mie_dialect_type_create(d, type_name); \
@@ -41,12 +43,13 @@
} }
#define __MIE_DIALECT_ADD_OP(op_id) \ #define __MIE_DIALECT_ADD_OP(op_id) \
extern struct mie_dialect_op *op_id##_op_create(struct mie_dialect *); \ extern struct mie_dialect_op *op_id##_op_create( \
op = op_id##_op_create(self) struct mie_dialect *, struct mie_ctx *); \
op = op_id##_op_create(self, ctx)
#define __MIE_DIALECT_ADD_TYPE(type_id) \ #define __MIE_DIALECT_ADD_TYPE(type_id) \
extern struct mie_dialect_type *type_id##_type_create( \ extern struct mie_dialect_type *type_id##_type_create( \
struct mie_dialect *); \ struct mie_dialect *, struct mie_ctx *); \
type = type_id##_type_create(self) type = type_id##_type_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()
@@ -65,8 +68,16 @@
#define MIE_DIALECT_TYPE_STRUCT(name) type->ty_data_size = sizeof(name) #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_INIT(func) type->ty_init = (func)
#define MIE_DIALECT_TYPE_PRINT(func) type->ty_print = (func) #define MIE_DIALECT_TYPE_PRINT(func) type->ty_print = (func)
#define MIE_DIALECT_TYPE_VALUE_PRINT(func) type->ty_value_print = (func)
#define MIE_DIALECT_TYPE_PARSE(func) type->ty_parse = (func) #define MIE_DIALECT_TYPE_PARSE(func) type->ty_parse = (func)
#define MIE_DIALECT_TYPE_BUILD_ID(func) type->ty_build_id = (func)
#define MIE_DIALECT_TYPE_INIT(func) type->ty_init = (func) #define MIE_DIALECT_TYPE_INIT(func) type->ty_init = (func)
#define MIE_DIALECT_TYPE_CLEANUP(func) type->ty_cleanup = (func) #define MIE_DIALECT_TYPE_CLEANUP(func) type->ty_cleanup = (func)
#define MIE_DIALECT_TRAIT_BEGIN(c_sym, trait)
#define MIE_DIALECT_TRAIT_END()
#define MIE_DIALECT_TRAIT_STRUCT(name)
#define MIE_DIALECT_TRAIT_PRINT(func)
#define MIE_DIALECT_TRAIT_CLEANUP(func)
#endif #endif

View File

@@ -14,4 +14,6 @@
#define MIN(x, y) ((x) < (y) ? (x) : (y)) #define MIN(x, y) ((x) < (y) ? (x) : (y))
#define MAX(x, y) ((x) > (y) ? (x) : (y)) #define MAX(x, y) ((x) > (y) ? (x) : (y))
#define MIE_TEST_FLAGS(value, flags) (((value) & (flags)) == (flags))
#endif #endif

View File

@@ -3,13 +3,21 @@
#include <blue/core/btree.h> #include <blue/core/btree.h>
#include <blue/core/queue.h> #include <blue/core/queue.h>
#include <mie/misc.h>
#include <mie/parse/file-span.h>
#define MIE_NAME_VALID(p) (((p)->n_str) != NULL) #define MIE_NAME_VALID(p) (((p)->n_str) != NULL)
struct mie_name_map; struct mie_name_map;
enum mie_name_map_flags { enum mie_name_map_flags {
MIE_NAME_MAP_STRICT = 0x01u, /* put(): take the name hint as the required name, and don't amend it
* to ensure uniqueness. if the given name already exists, the operation
* fails. */
MIE_NAME_MAP_F_STRICT = 0x01u,
/* get(): if the given name does not exist in the name map, recursively
* search the parent map(s) until a result is found. */
MIE_NAME_MAP_F_RECURSIVE = 0x02u,
}; };
enum mie_name_map_entry_type { enum mie_name_map_entry_type {
@@ -31,6 +39,10 @@ struct mie_name {
struct mie_name_map_entry n_base; struct mie_name_map_entry n_base;
struct mie_name_map *n_parent; struct mie_name_map *n_parent;
char *n_str; char *n_str;
/* if this name was read from a file, these structs can be used to
* record the location within the file where the name is found. */
struct mie_file_span n_start, n_end;
}; };
struct mie_name_bucket { struct mie_name_bucket {
@@ -39,13 +51,17 @@ struct mie_name_bucket {
}; };
struct mie_name_map { struct mie_name_map {
const struct mie_name_map *m_parent;
b_btree m_entries; b_btree m_entries;
size_t m_next_id; size_t m_next_id;
}; };
extern struct mie_name_map *mie_name_map_create(void); extern struct mie_name_map *mie_name_map_create(const struct mie_name_map *parent);
extern void mie_name_map_destroy(struct mie_name_map *map); extern void mie_name_map_destroy(struct mie_name_map *map);
extern const struct mie_name *mie_name_map_get(
const struct mie_name_map *map, const char *name,
enum mie_name_map_flags flags);
extern struct mie_name *mie_name_map_put( extern struct mie_name *mie_name_map_put(
struct mie_name_map *map, struct mie_name *entry, const char *hint, struct mie_name_map *map, struct mie_name *entry, const char *hint,
enum mie_name_map_flags flags); enum mie_name_map_flags flags);

View File

@@ -0,0 +1,23 @@
#ifndef MIE_PARSE_FILE_SPAN_H_
#define MIE_PARSE_FILE_SPAN_H_
#include <mie/misc.h>
struct mie_token;
/* a single row/column pair, representing a location within a file.
* both values are 1-based (i.e. the first character in a file is at c_row=1,
* c_col=1*/
struct mie_file_cell {
unsigned int c_row, c_col;
};
/* represents a span of characters within a file.
* used for diagnostic reporting */
struct mie_file_span {
struct mie_file_cell s_start, s_end;
};
MIE_API void mie_file_span_init(struct mie_file_span *span, struct mie_token *tok);
#endif

View File

@@ -2,18 +2,13 @@
#define MIE_PARSE_PARSE_H_ #define MIE_PARSE_PARSE_H_
#include <blue/ds/string.h> #include <blue/ds/string.h>
#include <mie/ir/register.h>
#include <mie/misc.h> #include <mie/misc.h>
#include <mie/parse/token.h> #include <mie/parse/token.h>
#include <mie/status.h> #include <mie/status.h>
#include <mie/vector.h> #include <mie/vector.h>
#include <stdbool.h> #include <stdbool.h>
enum mie_unresolved_operand_type {
MIE_UNRESOLVED_OPERAND_NONE = 0,
MIE_UNRESOLVED_OPERAND_VIRTUAL_REGISTER,
MIE_UNRESOLVED_OPERAND_MACHINE_REGISTER,
};
struct mie_parser; struct mie_parser;
struct mie_name_map; struct mie_name_map;
struct mie_lex; struct mie_lex;
@@ -23,20 +18,11 @@ struct mie_type;
struct mie_module; struct mie_module;
struct mie_region; struct mie_region;
struct mie_op; struct mie_op;
struct mie_op_arg;
struct mie_op_attribute; struct mie_op_attribute;
struct mie_op_successor; struct mie_op_successor;
struct mie_register; struct mie_register;
/* these structs are temporary, and are just here for documentation purposes atm */
struct mie_argument {
};
struct mie_unresolved_operand {
enum mie_unresolved_operand_type op_type;
b_string *op_name;
};
MIE_API struct mie_parser *mie_parser_create( MIE_API struct mie_parser *mie_parser_create(
struct mie_ctx *ctx, struct mie_lex *lex); struct mie_ctx *ctx, struct mie_lex *lex);
MIE_API void mie_parser_destroy(struct mie_parser *ctx); MIE_API void mie_parser_destroy(struct mie_parser *ctx);
@@ -52,31 +38,41 @@ MIE_API bool mie_parser_check_type(struct mie_parser *ctx, enum mie_token_type t
MIE_API bool mie_parser_check_symbol( MIE_API bool mie_parser_check_symbol(
struct mie_parser *ctx, enum mie_token_symbol sym); struct mie_parser *ctx, enum mie_token_symbol sym);
MIE_API bool mie_parser_parse_instname(struct mie_parser *ctx, b_string *out); MIE_API bool mie_parser_parse_word(
MIE_API bool mie_parser_parse_graphname(struct mie_parser *ctx, b_string *out); struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_opname(struct mie_parser *ctx, b_string *out); MIE_API bool mie_parser_parse_instname(
MIE_API bool mie_parser_parse_vregname(struct mie_parser *ctx, b_string *out); struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_mregname(struct mie_parser *ctx, b_string *out); MIE_API bool mie_parser_parse_graphname(
MIE_API bool mie_parser_parse_blockname(struct mie_parser *ctx, b_string *out); struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_typename(struct mie_parser *ctx, b_string *out); MIE_API bool mie_parser_parse_opname(
MIE_API bool mie_parser_parse_symname(struct mie_parser *ctx, b_string *out); struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_string(struct mie_parser *ctx, b_string *out); MIE_API bool mie_parser_parse_vregname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_mregname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_blockname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_typename(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_symname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_string(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_keyword(struct mie_parser *ctx, const char *kw); MIE_API bool mie_parser_parse_keyword(struct mie_parser *ctx, const char *kw);
MIE_API bool mie_parser_parse_symbol( MIE_API bool mie_parser_parse_symbol(
struct mie_parser *ctx, enum mie_token_symbol sym); struct mie_parser *ctx, enum mie_token_symbol sym);
MIE_API bool mie_parser_parse_assignment_list(
struct mie_parser *ctx, struct mie_argument **out_lhs,
struct mie_unresolved_operand **out_rhs, size_t *out_count);
MIE_API bool mie_parser_parse_type(struct mie_parser *ctx, struct mie_type **out); MIE_API bool mie_parser_parse_type(
struct mie_parser *ctx, const struct mie_type **out);
MIE_API bool mie_parser_parse_type_list( MIE_API bool mie_parser_parse_type_list(
struct mie_parser *ctx, MIE_VECTOR_PARAM(struct mie_type *, out)); struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(const struct mie_type *, out));
MIE_API bool mie_parser_parse_function_type(
struct mie_parser *ctx, struct mie_type **out);
MIE_API bool mie_parser_parse_operand( MIE_API bool mie_parser_parse_operand(
struct mie_parser *ctx, struct mie_unresolved_operand *out); struct mie_parser *ctx, struct mie_op_arg *out);
MIE_API bool mie_parser_parse_operand_list( MIE_API bool mie_parser_parse_operand_list(
struct mie_parser *ctx, struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out));
MIE_VECTOR_PARAM(struct mie_unresolved_operand, out));
MIE_API bool mie_parser_parse_unknown_keyword(struct mie_parser *ctx, b_string *out); MIE_API bool mie_parser_parse_unknown_keyword(struct mie_parser *ctx, b_string *out);
MIE_API bool mie_parser_parse_unknown_symbol( MIE_API bool mie_parser_parse_unknown_symbol(
@@ -87,22 +83,22 @@ MIE_API bool mie_parser_parse_register(
struct mie_register *out); struct mie_register *out);
MIE_API bool mie_parser_parse_register_list( MIE_API bool mie_parser_parse_register_list(
struct mie_parser *ctx, struct mie_name_map *names, struct mie_parser *ctx, struct mie_name_map *names,
MIE_VECTOR_PARAM(struct mie_register, out)); MIE_VECTOR_REF_PARAM(struct mie_register, out));
MIE_API bool mie_parser_parse_region( MIE_API bool mie_parser_parse_region(
struct mie_parser *ctx, struct mie_region *region); struct mie_parser *ctx, struct mie_region *region);
MIE_API bool mie_parser_parse_region_list( MIE_API bool mie_parser_parse_region_list(
struct mie_parser *ctx, MIE_VECTOR_PARAM(struct mie_region, out)); struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_region, out));
MIE_API bool mie_parser_parse_attribute( MIE_API bool mie_parser_parse_attribute(
struct mie_parser *ctx, struct mie_op_attribute *attrib); struct mie_parser *ctx, struct mie_op_attribute *attrib);
MIE_API bool mie_parser_parse_attribute_list( MIE_API bool mie_parser_parse_attribute_list(
struct mie_parser *ctx, MIE_VECTOR_PARAM(struct mie_op_attribute, out)); struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_attribute, out));
MIE_API bool mie_parser_parse_successor( MIE_API bool mie_parser_parse_successor(
struct mie_parser *ctx, struct mie_op_successor *successor); struct mie_parser *ctx, struct mie_op_successor *successor);
MIE_API bool mie_parser_parse_successor_list( MIE_API bool mie_parser_parse_successor_list(
struct mie_parser *ctx, MIE_VECTOR_PARAM(struct mie_op_successor, out)); struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_successor, out));
MIE_API bool mie_parser_parse_module(struct mie_parser *ctx, struct mie_module *mod); MIE_API bool mie_parser_parse_module(struct mie_parser *ctx, struct mie_module *mod);
MIE_API bool mie_parser_parse_op( MIE_API bool mie_parser_parse_op(

View File

@@ -3,6 +3,7 @@
#include <blue/core/queue.h> #include <blue/core/queue.h>
#include <mie/misc.h> #include <mie/misc.h>
#include <mie/parse/file-span.h>
#define MIE_TOKEN_TYPE(tok) ((tok) ? (tok)->tok_type : MIE_TOK_NONE) #define MIE_TOKEN_TYPE(tok) ((tok) ? (tok)->tok_type : MIE_TOK_NONE)
#define MIE_TOKEN_IS(tok, type) ((tok) && ((tok)->tok_type & (type)) != 0) #define MIE_TOKEN_IS(tok, type) ((tok) && ((tok)->tok_type & (type)) != 0)
@@ -72,12 +73,8 @@ enum mie_token_symbol {
MIE_SYM_OTHER, MIE_SYM_OTHER,
}; };
struct mie_token_location {
unsigned int c_row, c_col;
};
struct mie_token { struct mie_token {
struct mie_token_location tok_start, tok_end; struct mie_file_span tok_location;
enum mie_token_type tok_type; enum mie_token_type tok_type;
enum mie_token_value_type tok_value_type; enum mie_token_value_type tok_value_type;
b_queue_entry tok_entry; b_queue_entry tok_entry;

View File

@@ -0,0 +1,39 @@
#ifndef MIE_TRAIT_TRAIT_TABLE_H_
#define MIE_TRAIT_TRAIT_TABLE_H_
#include <blue/core/btree.h>
#include <mie/id.h>
#include <mie/misc.h>
#include <mie/status.h>
/* for IR objects that support traits (ops, types, etc), this struct can be used
* to store and retrieve references to the traits that apply */
struct mie_trait_table {
struct mie_id_map tr_unique;
struct mie_id_map tr_generic;
};
struct mie_trait_table_iterator {
const struct mie_trait *it_trait;
b_queue_entry *_e;
};
MIE_API void mie_trait_table_init(struct mie_trait_table *out);
MIE_API void mie_trait_table_cleanup(struct mie_trait_table *table);
/* retrieve a trait based on its name. this function can only be used to
* retrieve non-parametised traits. to retrieve parametised traits, use
* mie_trait_table_get_generic. */
MIE_API const struct mie_trait *mie_trait_table_get_unique(
const struct mie_trait_table *table, const char *dialect_name,
const char *trait_name);
MIE_API enum mie_status mie_trait_table_get_generic(
const struct mie_trait_table *table, const char *dialect_name,
const char *trait_name, struct mie_trait_table_iterator *it);
MIE_API enum mie_status mie_trait_table_put(
struct mie_trait_table *table, const struct mie_trait *trait);
MIE_API enum mie_status mie_trait_table_iterator_move_next(
struct mie_trait_table_iterator *it);
#endif

View File

@@ -0,0 +1,42 @@
#ifndef MIE_TRAIT_TRAIT_H_
#define MIE_TRAIT_TRAIT_H_
#include <mie/id.h>
struct mie_trait;
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,
};
/* 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;
/* 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 *);
};
/* used to link an op/type/etc to a trait. if the trait is parametised, this
* struct includes any parameter values. */
struct mie_trait {
/* this is NOT the same as tr_def->tr_id */
mie_id tr_id;
const struct mie_trait_definition *tr_def;
};
#endif

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,22 +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;
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); 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

View File

@@ -4,37 +4,64 @@
#include <mie/misc.h> #include <mie/misc.h>
#include <stddef.h> #include <stddef.h>
#if 0
#define MIE_VECTOR_DEFINE(type, name) \ #define MIE_VECTOR_DEFINE(type, name) \
size_t name##_count = 0; \ size_t name##_count = 0; \
size_t name##_max = 0; \ size_t name##_max = 0; \
type *name = NULL type *name = NULL
#endif
#define MIE_VECTOR_DEFINE(type, name) \
struct { \
size_t count; \
size_t max; \
type *items; \
} name = {0}
#define MIE_VECTOR_DECLARE(type, name) \ #define MIE_VECTOR_DECLARE(type, name) \
size_t name##_count; \ struct { \
size_t name##_max; \ size_t count; \
type *name size_t max; \
type *items; \
} name
#define MIE_VECTOR_COUNT(name) name##_count #define MIE_VECTOR_ITEM(name, index) name.items[index]
#define MIE_VECTOR_MAX(name) name##_max #define MIE_VECTOR_ITEM_PTR(name, index) &name.items[index]
#define MIE_VECTOR_COUNT(name) name.count
#define MIE_VECTOR_MAX(name) name.max
#define MIE_VECTOR_PARAM(type, name) \ /* use this macros in your function prototype, to allow the function to accept
* a reference to a vector as a parameter */
#define MIE_VECTOR_REF_PARAM(type, name) \
type **name, size_t *name##_count, size_t *name##_max type **name, size_t *name##_count, size_t *name##_max
#define MIE_VECTOR_ARG(name) &(name), &(name##_count), &(name##_max) /* use this macro to pass a reference to a vector as a parameter to a function
#define MIE_VECTOR_REF_ARG(name) (name), (name##_count), (name##_max) * whose prototype uses MIE_VECTOR_REF_PARAM */
#define MIE_VECTOR_REF(name) &(name.items), &(name.count), &(name.max)
/* use this macro to forward your reference to a vector (which you got via
* MIE_VECTOR_REF_PARAM in your function prototype), to another function whose
* prototype also uses MIE_VECTOR_REF_PARAM */
#define MIE_VECTOR_REF2(name) &(name.items), &(name.count), &(name.max)
/* use these functions if you're accessing a vector directly. */
#define mie_vector_push_back(vector, ptr) \ #define mie_vector_push_back(vector, ptr) \
__mie_vector_push_back( \ __mie_vector_push_back( \
(void **)&(vector), ptr, sizeof *ptr, &(vector##_count), \ (void **)&(vector.items), ptr, sizeof *ptr, &(vector.count), \
&(vector##_max)) &(vector.max))
#define mie_vector_pop_back(vector) \ #define mie_vector_pop_back(vector) \
__mie_vector_pop_back( \ __mie_vector_pop_back( \
(void **)&(vector), sizeof *vector, &(vector##_count), \ (void **)&(vector), sizeof *vector, &(vector.count), \
&(vector##_max)) &(vector.max))
#define mie_vector_emplace_back(vector) \ #define mie_vector_emplace_back(vector) \
__mie_vector_emplace_back( \ __mie_vector_emplace_back( \
(void **)&(vector), sizeof *vector, &(vector##_count), \ (void **)&(vector.items), sizeof *vector.items, \
&(vector##_max)) &(vector.count), &(vector.max))
#define mie_vector_destroy(vector, dtor) \
__mie_vector_destroy( \
(void **)&(vector.items), sizeof *vector.items, \
&(vector.count), &(vector.max), dtor)
/* use these functions if you're accessing a vector as a reference
* via MIE_VECTOR_REF_PARAM. */
#define mie_vector_ref_push_back(vector, ptr) \ #define mie_vector_ref_push_back(vector, ptr) \
__mie_vector_push_back( \ __mie_vector_push_back( \
(void **)(vector), ptr, sizeof *ptr, (vector##_count), \ (void **)(vector), ptr, sizeof *ptr, (vector##_count), \
@@ -47,18 +74,15 @@
__mie_vector_emplace_back( \ __mie_vector_emplace_back( \
(void **)(vector), sizeof **vector, (vector##_count), \ (void **)(vector), sizeof **vector, (vector##_count), \
(vector##_max)) (vector##_max))
#define mie_vector_destroy(vector, dtor) \
__mie_vector_destroy( \
(void **)&(vector), sizeof *vector, &(vector##_count), \
&(vector##_max), dtor)
#define mie_vector_ref_destroy(vector, dtor) \ #define mie_vector_ref_destroy(vector, dtor) \
__mie_vector_destroy( \ __mie_vector_destroy( \
(void **)(vector), sizeof **vector, (vector##_count), \ (void **)(vector), sizeof **vector, (vector##_count), \
(vector##_max), dtor) (vector##_max), dtor)
/* don't use these functions */
MIE_API int __mie_vector_push_back( MIE_API int __mie_vector_push_back(
void **vector, void *item, size_t item_size, size_t *count, size_t *max); void **vector, const void *item, size_t item_size, size_t *count,
size_t *max);
MIE_API void __mie_vector_pop_back( MIE_API void __mie_vector_pop_back(
void **vector, size_t item_size, size_t *count, size_t *max); void **vector, size_t item_size, size_t *count, size_t *max);
MIE_API void *__mie_vector_emplace_back( MIE_API void *__mie_vector_emplace_back(

View File

@@ -4,9 +4,10 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
B_BTREE_DEFINE_SIMPLE_INSERT(struct mie_name_map_entry, e_node, e_hash, put_entry) static B_BTREE_DEFINE_SIMPLE_INSERT(
B_BTREE_DEFINE_SIMPLE_GET( struct mie_name_map_entry, e_node, e_hash, put_entry);
struct mie_name_map_entry, uint64_t, e_node, e_hash, get_entry) static B_BTREE_DEFINE_SIMPLE_GET(
struct mie_name_map_entry, uint64_t, e_node, e_hash, get_entry);
static struct mie_name_bucket *create_bucket(void) static struct mie_name_bucket *create_bucket(void)
{ {
@@ -36,7 +37,7 @@ static void destroy_bucket(struct mie_name_bucket *bucket)
free(bucket); free(bucket);
} }
struct mie_name_map *mie_name_map_create(void) struct mie_name_map *mie_name_map_create(const struct mie_name_map *parent)
{ {
struct mie_name_map *out = malloc(sizeof *out); struct mie_name_map *out = malloc(sizeof *out);
if (!out) { if (!out) {
@@ -44,6 +45,8 @@ struct mie_name_map *mie_name_map_create(void)
} }
memset(out, 0x0, sizeof *out); memset(out, 0x0, sizeof *out);
out->m_parent = parent;
return out; return out;
} }
@@ -127,6 +130,80 @@ static b_status put_name(struct mie_name_map *map, struct mie_name *name)
return B_SUCCESS; return B_SUCCESS;
} }
static bool check_name(const struct mie_name *name, const char *s, uint64_t hash)
{
return name->n_base.e_hash == hash && !strcmp(name->n_str, s);
}
static const struct mie_name *find_name_in_bucket(
const struct mie_name_bucket *bucket, const char *s, uint64_t hash)
{
b_queue_entry *entry = b_queue_first(&bucket->b_names);
while (entry) {
struct mie_name_map_entry *map_entry
= b_unbox(struct mie_name_map_entry, entry, e_entry);
struct mie_name *name = (struct mie_name *)map_entry;
if (check_name(name, s, hash)) {
return name;
}
entry = b_queue_next(entry);
}
return NULL;
}
static const struct mie_name *name_map_get(
const struct mie_name_map *map, const char *name, uint64_t name_hash)
{
const struct mie_name_map_entry *entry
= get_entry(&map->m_entries, name_hash);
if (!entry) {
return NULL;
}
const struct mie_name *name_entry = NULL;
struct mie_name_bucket *bucket = NULL;
switch (entry->e_type) {
case MIE_NAME_MAP_E_NAME:
name_entry = (struct mie_name *)entry;
if (check_name(name_entry, name, name_hash)) {
return name_entry;
}
break;
case MIE_NAME_MAP_E_BUCKET:
bucket = (struct mie_name_bucket *)entry;
name_entry = find_name_in_bucket(bucket, name, name_hash);
if (name_entry) {
return name_entry;
}
break;
default:
break;
}
return NULL;
}
const struct mie_name *mie_name_map_get(
const struct mie_name_map *map, const char *name,
enum mie_name_map_flags flags)
{
uint64_t name_hash = b_hash_cstr(name);
while (map) {
const struct mie_name *result = name_map_get(map, name, name_hash);
if (result) {
return result;
}
map = (flags & MIE_NAME_MAP_F_RECURSIVE) ? map->m_parent : NULL;
}
return NULL;
}
struct mie_name *mie_name_map_put( struct mie_name *mie_name_map_put(
struct mie_name_map *map, struct mie_name *entry, const char *hint, struct mie_name_map *map, struct mie_name *entry, const char *hint,
enum mie_name_map_flags flags) enum mie_name_map_flags flags)
@@ -156,7 +233,7 @@ struct mie_name *mie_name_map_put(
} }
} }
if (flags & MIE_NAME_MAP_STRICT) { if (flags & MIE_NAME_MAP_F_STRICT) {
/* the caller insists that `hint` be used as the name. /* the caller insists that `hint` be used as the name.
* such a name already exists, so we can't help them */ * such a name already exists, so we can't help them */
return NULL; return NULL;

7
mie/parse/file-span.c Normal file
View File

@@ -0,0 +1,7 @@
#include <mie/parse/file-span.h>
#include <mie/parse/token.h>
void mie_file_span_init(struct mie_file_span *span, struct mie_token *tok)
{
*span = tok->tok_location;
}

View File

@@ -324,10 +324,10 @@ static void set_token_end(struct mie_lex *lex)
static enum mie_status push_token(struct mie_lex *lex, struct mie_token *tok) static enum mie_status push_token(struct mie_lex *lex, struct mie_token *tok)
{ {
tok->tok_start.c_row = lex->lex_token_start_row; tok->tok_location.s_start.c_row = lex->lex_token_start_row;
tok->tok_start.c_col = lex->lex_token_start_col; tok->tok_location.s_start.c_col = lex->lex_token_start_col;
tok->tok_end.c_row = lex->lex_token_end_row; tok->tok_location.s_end.c_row = lex->lex_token_end_row;
tok->tok_end.c_col = lex->lex_token_end_col; tok->tok_location.s_end.c_col = lex->lex_token_end_col;
b_queue_push_back(&lex->lex_queue, &tok->tok_entry); b_queue_push_back(&lex->lex_queue, &tok->tok_entry);
return MIE_SUCCESS; return MIE_SUCCESS;

View File

@@ -1,3 +1,7 @@
#include <mie/ctx.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/type.h>
#include <mie/ir/module.h> #include <mie/ir/module.h>
#include <mie/ir/op.h> #include <mie/ir/op.h>
#include <mie/ir/region.h> #include <mie/ir/region.h>
@@ -5,6 +9,7 @@
#include <mie/parse/lex.h> #include <mie/parse/lex.h>
#include <mie/parse/parse.h> #include <mie/parse/parse.h>
#include <mie/parse/token.h> #include <mie/parse/token.h>
#include <mie/type/function.h>
struct mie_parser { struct mie_parser {
struct mie_ctx *p_ctx; struct mie_ctx *p_ctx;
@@ -80,41 +85,32 @@ bool mie_parser_advance(struct mie_parser *ctx)
return mie_lex_get_status(ctx->p_lex) == MIE_SUCCESS; return mie_lex_get_status(ctx->p_lex) == MIE_SUCCESS;
} }
bool mie_parser_parse_vregname(struct mie_parser *ctx, b_string *out) #define TOKEN_PARSER(name, id) \
{ bool mie_parser_parse_##name( \
if (!mie_parser_check_type(ctx, MIE_TOK_VREGNAME)) { struct mie_parser *ctx, b_string *out, struct mie_file_span *loc) \
return false; { \
if (!mie_parser_check_type(ctx, id)) { \
return false; \
} \
struct mie_token *tok = mie_lex_peek(ctx->p_lex); \
b_string_append_cstr(out, tok->tok_str); \
if (loc) { \
mie_file_span_init(loc, tok); \
} \
mie_lex_advance(ctx->p_lex); \
return true; \
} }
struct mie_token *tok = mie_lex_peek(ctx->p_lex); TOKEN_PARSER(word, MIE_TOK_WORD);
b_string_append_cstr(out, tok->tok_str); TOKEN_PARSER(instname, MIE_TOK_INSTNAME);
mie_lex_advance(ctx->p_lex); TOKEN_PARSER(graphname, MIE_TOK_GRAPHNAME);
return true; TOKEN_PARSER(opname, MIE_TOK_OPNAME);
} TOKEN_PARSER(vregname, MIE_TOK_VREGNAME);
TOKEN_PARSER(mregname, MIE_TOK_MREGNAME);
bool mie_parser_parse_mregname(struct mie_parser *ctx, b_string *out) TOKEN_PARSER(blockname, MIE_TOK_BLOCKNAME);
{ TOKEN_PARSER(typename, MIE_TOK_TYPENAME);
if (!mie_parser_check_type(ctx, MIE_TOK_MREGNAME)) { TOKEN_PARSER(symname, MIE_TOK_SYMNAME);
return false; TOKEN_PARSER(string, MIE_TOK_STRING);
}
struct mie_token *tok = mie_lex_peek(ctx->p_lex);
b_string_append_cstr(out, tok->tok_str);
mie_lex_advance(ctx->p_lex);
return true;
}
bool mie_parser_parse_opname(struct mie_parser *ctx, b_string *out)
{
if (!mie_parser_check_type(ctx, MIE_TOK_OPNAME)) {
return false;
}
struct mie_token *tok = mie_lex_peek(ctx->p_lex);
b_string_append_cstr(out, tok->tok_str);
mie_lex_advance(ctx->p_lex);
return true;
}
bool mie_parser_parse_symbol(struct mie_parser *ctx, enum mie_token_symbol sym) bool mie_parser_parse_symbol(struct mie_parser *ctx, enum mie_token_symbol sym)
{ {
@@ -127,16 +123,155 @@ bool mie_parser_parse_symbol(struct mie_parser *ctx, enum mie_token_symbol sym)
return true; return true;
} }
bool mie_parser_parse_type(struct mie_parser *ctx, struct mie_type **out) static bool parse_builtin_type_name(
struct mie_parser *ctx, const struct mie_type **out)
{ {
b_string *name = b_string_create();
struct mie_file_span loc;
if (!mie_parser_parse_word(ctx, name, &loc)) {
b_string_unref(name);
return false;
}
const struct mie_dialect_type *type_info = NULL;
const struct mie_type *type = NULL;
size_t width = 0;
char tmp = 0;
enum {
NONE = 0,
INT,
FLOAT
} base_type = NONE;
const char *name_cstr = b_string_ptr(name);
if (!strcmp(name_cstr, "memref")) {
type_info = mie_ctx_get_dialect_type(
ctx->p_ctx, "memref", "memref");
} else if (!strcmp(name_cstr, "index")) {
type_info
= mie_ctx_get_dialect_type(ctx->p_ctx, "index", "index");
} else if (!strcmp(name_cstr, "str")) {
type_info = mie_ctx_get_dialect_type(
ctx->p_ctx, "builtin", "string");
} else if (sscanf(name_cstr, "i%zu%c", &width, &tmp) == 1) {
type_info = mie_ctx_get_dialect_type(ctx->p_ctx, "arith", "int");
base_type = INT;
} else if (sscanf(name_cstr, "f%zu%c", &width, &tmp) == 1) {
type_info
= mie_ctx_get_dialect_type(ctx->p_ctx, "arith", "float");
base_type = FLOAT;
}
if (!type_info) {
return false;
}
switch (base_type) {
case INT:
type = mie_arith_int_get_type(ctx->p_ctx, width);
break;
case FLOAT:
type = mie_arith_float_get_type(ctx->p_ctx, width);
break;
default:
type = mie_ctx_get_type(
ctx->p_ctx, type_info->ty_parent->d_name,
type_info->ty_name);
break;
}
*out = type;
return type != NULL;
}
static bool parse_type_name(struct mie_parser *ctx, const struct mie_type **out)
{
b_string *name = b_string_create();
struct mie_file_span loc;
if (!mie_parser_parse_typename(ctx, name, &loc)) {
b_string_unref(name);
return false;
}
*out = NULL;
return false; return false;
} }
static bool parse_composite_type(struct mie_parser *ctx, const struct mie_type **out)
{
const struct mie_type *temp = NULL;
MIE_VECTOR_DEFINE(const struct mie_type *, type_list_1);
MIE_VECTOR_DEFINE(const struct mie_type *, type_list_2);
if (!mie_parser_parse_type_list(ctx, MIE_VECTOR_REF(type_list_1))) {
return false;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_HYPHEN_RIGHT_ANGLE)) {
*out = mie_ctx_get_storage_type(
ctx->p_ctx, type_list_1.items, type_list_1.count);
return *out != NULL;
}
bool ok = false;
if (mie_parser_peek_symbol(ctx) == MIE_SYM_LEFT_PAREN) {
ok = mie_parser_parse_type_list(ctx, MIE_VECTOR_REF(type_list_2));
} else {
ok = mie_parser_parse_type(ctx, &temp);
if (temp) {
mie_vector_push_back(type_list_2, &temp);
}
}
if (!ok) {
mie_vector_destroy(type_list_1, NULL);
mie_vector_destroy(type_list_2, NULL);
return false;
}
temp = mie_ctx_get_function_type(
ctx->p_ctx, type_list_1.items, type_list_1.count,
type_list_2.items, type_list_2.count);
mie_vector_destroy(type_list_1, NULL);
mie_vector_destroy(type_list_2, NULL);
*out = temp;
return temp != NULL;
}
bool mie_parser_parse_type(struct mie_parser *ctx, const struct mie_type **out)
{
if (mie_parser_peek_symbol(ctx) == MIE_SYM_LEFT_PAREN) {
return parse_composite_type(ctx, out);
}
switch (mie_parser_peek_type(ctx)) {
case MIE_TOK_WORD:
return parse_builtin_type_name(ctx, out);
case MIE_TOK_TYPENAME:
return parse_type_name(ctx, out);
default:
return false;
}
}
bool mie_parser_parse_type_list( bool mie_parser_parse_type_list(
struct mie_parser *ctx, MIE_VECTOR_PARAM(struct mie_type *, out)) struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(const struct mie_type *, out))
{ {
bool ok = false; bool ok = false;
struct mie_type **type_slot = NULL; const struct mie_type **type_slot = NULL;
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
return false;
}
if (mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) {
/* empty type list */
return true;
}
type_slot = mie_vector_ref_emplace_back(out); type_slot = mie_vector_ref_emplace_back(out);
if (!type_slot) { if (!type_slot) {
@@ -164,32 +299,83 @@ bool mie_parser_parse_type_list(
} }
} }
return true; if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) {
}
bool mie_parser_parse_operand(
struct mie_parser *ctx, struct mie_unresolved_operand *out)
{
memset(out, 0x0, sizeof *out);
out->op_name = b_string_create();
if (mie_parser_parse_vregname(ctx, out->op_name)) {
out->op_type = MIE_UNRESOLVED_OPERAND_VIRTUAL_REGISTER;
} else if (mie_parser_parse_mregname(ctx, out->op_name)) {
out->op_type = MIE_UNRESOLVED_OPERAND_MACHINE_REGISTER;
} else {
b_string_unref(out->op_name);
return false; return false;
} }
return true; return true;
} }
MIE_API bool mie_parser_parse_function_type(
struct mie_parser *ctx, struct mie_type **out)
{
const struct mie_type *type = NULL;
MIE_VECTOR_DEFINE(const struct mie_type *, in_parts);
MIE_VECTOR_DEFINE(const struct mie_type *, out_parts);
if (!mie_parser_parse_type_list(ctx, MIE_VECTOR_REF(in_parts))) {
return false;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_HYPHEN_RIGHT_ANGLE)) {
mie_vector_destroy(in_parts, NULL);
mie_vector_destroy(out_parts, NULL);
return false;
}
bool ok = false;
if (mie_parser_peek_symbol(ctx) == MIE_SYM_LEFT_PAREN) {
ok = mie_parser_parse_type_list(ctx, MIE_VECTOR_REF(out_parts));
} else {
ok = mie_parser_parse_type(ctx, &type);
if (type) {
mie_vector_push_back(out_parts, &type);
}
}
if (!ok) {
mie_vector_destroy(in_parts, NULL);
mie_vector_destroy(out_parts, NULL);
return false;
}
type = mie_ctx_get_function_type(
ctx->p_ctx, in_parts.items, in_parts.count, out_parts.items,
out_parts.count);
mie_vector_destroy(in_parts, NULL);
mie_vector_destroy(out_parts, NULL);
*out = (struct mie_type *)type;
return type != NULL;
}
bool mie_parser_parse_operand(struct mie_parser *ctx, struct mie_op_arg *out)
{
memset(out, 0x0, sizeof *out);
b_string *str = b_string_create();
bool result = false;
struct mie_file_span loc;
if (mie_parser_parse_vregname(ctx, str, &loc)) {
out->arg_unresolved.reg_name = b_string_steal(str);
out->arg_unresolved.reg_flags = MIE_REGISTER_F_VIRTUAL;
result = true;
} else if (mie_parser_parse_mregname(ctx, str, &loc)) {
out->arg_unresolved.reg_name = b_string_steal(str);
out->arg_unresolved.reg_flags = MIE_REGISTER_F_MACHINE;
result = true;
}
b_string_unref(str);
return result;
}
bool mie_parser_parse_operand_list( bool mie_parser_parse_operand_list(
struct mie_parser *ctx, struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out))
MIE_VECTOR_PARAM(struct mie_unresolved_operand, out))
{ {
bool ok = false; bool ok = false;
struct mie_unresolved_operand *operand = NULL; struct mie_op_arg *operand = NULL;
struct mie_token *tok = mie_parser_peek(ctx); struct mie_token *tok = mie_parser_peek(ctx);
enum mie_token_type type = MIE_TOKEN_TYPE(tok); enum mie_token_type type = MIE_TOKEN_TYPE(tok);
@@ -253,7 +439,7 @@ bool mie_parser_parse_register(
} }
if (!mie_name_map_put( if (!mie_name_map_put(
names, &out->reg_name, tok->tok_str, MIE_NAME_MAP_STRICT)) { names, &out->reg_name, tok->tok_str, MIE_NAME_MAP_F_STRICT)) {
return false; return false;
} }
@@ -264,7 +450,7 @@ bool mie_parser_parse_register(
bool mie_parser_parse_register_list( bool mie_parser_parse_register_list(
struct mie_parser *ctx, struct mie_name_map *names, struct mie_parser *ctx, struct mie_name_map *names,
MIE_VECTOR_PARAM(struct mie_register, out)) MIE_VECTOR_REF_PARAM(struct mie_register, out))
{ {
bool ok = false; bool ok = false;
struct mie_register *reg = NULL; struct mie_register *reg = NULL;
@@ -344,7 +530,7 @@ bool mie_parser_parse_region(struct mie_parser *ctx, struct mie_region *region)
} }
bool mie_parser_parse_region_list( bool mie_parser_parse_region_list(
struct mie_parser *ctx, MIE_VECTOR_PARAM(struct mie_region, out)) struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_region, out))
{ {
if (!mie_parser_check_symbol(ctx, MIE_SYM_LEFT_BRACE)) { if (!mie_parser_check_symbol(ctx, MIE_SYM_LEFT_BRACE)) {
return false; return false;
@@ -382,7 +568,7 @@ bool mie_parser_parse_attribute(
} }
bool mie_parser_parse_attribute_list( bool mie_parser_parse_attribute_list(
struct mie_parser *ctx, MIE_VECTOR_PARAM(struct mie_op_attribute, out)) struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_attribute, out))
{ {
return false; return false;
} }
@@ -394,7 +580,7 @@ bool mie_parser_parse_successor(
} }
bool mie_parser_parse_successor_list( bool mie_parser_parse_successor_list(
struct mie_parser *ctx, MIE_VECTOR_PARAM(struct mie_op_successor, out)) struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_successor, out))
{ {
return false; return false;
} }
@@ -409,19 +595,20 @@ static bool parse_generic_op(
struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest) struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest)
{ {
b_string *str = b_string_create(); b_string *str = b_string_create();
if (!mie_parser_parse_opname(ctx, str)) { struct mie_file_span loc;
if (!mie_parser_parse_opname(ctx, str, &loc)) {
b_string_unref(str);
return false; return false;
} }
dest->op_name = b_string_steal(str); dest->op_name = b_string_steal(str);
b_string_unref(str);
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) { if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
return false; return false;
} }
MIE_VECTOR_DEFINE(struct mie_unresolved_operand, operands); if (!mie_parser_parse_operand_list(ctx, MIE_VECTOR_REF(dest->op_args))) {
if (mie_parser_parse_operand_list(ctx, MIE_VECTOR_ARG(operands))) {
return false; return false;
} }
@@ -431,7 +618,7 @@ static bool parse_generic_op(
if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACKET)) { if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACKET)) {
if (!mie_parser_parse_successor_list( if (!mie_parser_parse_successor_list(
ctx, MIE_VECTOR_ARG(dest->op_successors))) { ctx, MIE_VECTOR_REF(dest->op_successors))) {
return false; return false;
} }
@@ -442,7 +629,7 @@ static bool parse_generic_op(
if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) { if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
if (!mie_parser_parse_region_list( if (!mie_parser_parse_region_list(
ctx, MIE_VECTOR_ARG(dest->op_regions))) { ctx, MIE_VECTOR_REF(dest->op_regions))) {
return false; return false;
} }
@@ -453,7 +640,7 @@ static bool parse_generic_op(
if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACE)) { if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACE)) {
if (!mie_parser_parse_attribute_list( if (!mie_parser_parse_attribute_list(
ctx, MIE_VECTOR_ARG(dest->op_attrib))) { ctx, MIE_VECTOR_REF(dest->op_attrib))) {
return false; return false;
} }
@@ -466,15 +653,29 @@ static bool parse_generic_op(
return false; return false;
} }
/* parse input type list */ struct mie_function_type *func_type = NULL;
if (!mie_parser_parse_function_type(ctx, (struct mie_type **)&func_type)) {
if (!mie_parser_parse_symbol(ctx, MIE_SYM_HYPHEN_RIGHT_ANGLE)) {
return false; return false;
} }
/* parse output type list */ if (MIE_VECTOR_COUNT(func_type->func_in)
!= MIE_VECTOR_COUNT(dest->op_args)) {
return false;
}
mie_vector_destroy(operands, NULL); if (MIE_VECTOR_COUNT(func_type->func_out)
!= MIE_VECTOR_COUNT(dest->op_result)) {
return false;
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(func_type->func_in); i++) {
dest->op_args.items[i].arg_unresolved.reg_type
= func_type->func_in.items[i];
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(func_type->func_out); i++) {
dest->op_result.items[i].reg_type = func_type->func_out.items[i];
}
return true; return true;
} }
@@ -496,7 +697,7 @@ bool mie_parser_parse_op(
if (mie_parser_check_type(ctx, MIE_TOK_MREGNAME | MIE_TOK_VREGNAME)) { if (mie_parser_check_type(ctx, MIE_TOK_MREGNAME | MIE_TOK_VREGNAME)) {
if (!mie_parser_parse_register_list( if (!mie_parser_parse_register_list(
ctx, names, MIE_VECTOR_ARG(dest->op_result))) { ctx, names, MIE_VECTOR_REF(dest->op_result))) {
return false; return false;
} }

183
mie/trait/trait-table.c Normal file
View File

@@ -0,0 +1,183 @@
#include <mie/trait/trait-table.h>
#include <mie/trait/trait.h>
#define UNIQUE_TRAIT_NS_ID \
MIE_ID(0xd6, 0xb6, 0x72, 0xae, 0xef, 0x65, 0x40, 0x24, 0xaa, 0x6d, \
0xef, 0xfc, 0x37, 0xda, 0x5c, 0x88)
#define GENERIC_TRAIT_NS_ID \
MIE_ID(0x1a, 0x60, 0xbe, 0x20, 0xa6, 0xa0, 0x43, 0x3a, 0xb1, 0x2c, \
0x33, 0x9a, 0xac, 0x52, 0xa0, 0xca)
struct unique_trait {
mie_id u_id;
const struct mie_trait *u_trait;
};
struct generic_trait {
/* generic trait ID. */
mie_id g_id;
/* list of struct unique_trait */
b_queue g_traits;
};
static struct unique_trait *unique_trait_create(const struct mie_trait *trait)
{
struct unique_trait *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->u_id = trait->tr_id;
out->u_trait = trait;
return out;
}
static void unique_trait_destroy(struct unique_trait *trait)
{
free(trait);
}
static struct generic_trait *generic_trait_create(const struct mie_trait *trait)
{
struct generic_trait *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->g_id = trait->tr_def->tr_id;
struct unique_trait *entry = unique_trait_create(trait);
if (!entry) {
free(out);
return NULL;
}
b_queue_push_back(&out->g_traits, &entry->u_id.e_entry);
return out;
}
static void generic_trait_destroy(struct generic_trait *trait)
{
b_queue_entry *cur = b_queue_first(&trait->g_traits);
while (cur) {
b_queue_entry *next = b_queue_next(cur);
b_queue_delete(&trait->g_traits, cur);
struct unique_trait *u
= b_unbox(struct unique_trait, cur, u_id.e_entry);
unique_trait_destroy(u);
cur = next;
}
free(trait);
}
void mie_trait_table_init(struct mie_trait_table *out)
{
memset(out, 0x0, sizeof *out);
mie_id unique_ns = UNIQUE_TRAIT_NS_ID;
mie_id_map_init(&out->tr_unique, &unique_ns);
mie_id generic_ns = GENERIC_TRAIT_NS_ID;
mie_id_map_init(&out->tr_generic, &generic_ns);
}
void mie_trait_table_cleanup(struct mie_trait_table *table)
{
/* TODO */
}
const struct mie_trait *mie_trait_table_get_unique(
const struct mie_trait_table *table, const char *dialect_name,
const char *trait_name)
{
mie_id id;
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, dialect_name);
mie_id_builder_add_char(&id_ctx, '.');
mie_id_builder_add_cstr(&id_ctx, trait_name);
mie_id_builder_end(&id_ctx, &id);
const mie_id *result = mie_id_map_get(&table->tr_unique, &id);
const struct unique_trait *entry
= b_unbox(struct unique_trait, entry, u_id);
return entry ? entry->u_trait : NULL;
}
static enum mie_status put_unique_trait(
struct mie_trait_table *table, const struct mie_trait *trait)
{
return MIE_SUCCESS;
}
static enum mie_status put_generic_trait(
struct mie_trait_table *table, const struct mie_trait *trait)
{
return MIE_SUCCESS;
}
enum mie_status mie_trait_table_put(
struct mie_trait_table *table, const struct mie_trait *trait)
{
if (trait->tr_def->tr_flags & MIE_TRAIT_F_PARAMETISED) {
return put_generic_trait(table, trait);
}
return put_unique_trait(table, trait);
}
enum mie_status mie_trait_table_get_generic(
const struct mie_trait_table *table, const char *dialect_name,
const char *trait_name, struct mie_trait_table_iterator *it)
{
mie_id id;
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, dialect_name);
mie_id_builder_add_char(&id_ctx, '.');
mie_id_builder_add_cstr(&id_ctx, trait_name);
mie_id_builder_end(&id_ctx, &id);
const mie_id *result = mie_id_map_get(&table->tr_unique, &id);
const struct generic_trait *entry
= b_unbox(struct generic_trait, entry, g_id);
if (!entry || b_queue_empty(&entry->g_traits)) {
return MIE_ERR_NO_ENTRY;
}
memset(it, 0x0, sizeof *it);
it->_e = b_queue_first(&entry->g_traits);
struct unique_trait *trait
= b_unbox(struct unique_trait, it->_e, u_id.e_entry);
it->it_trait = trait->u_trait;
return MIE_SUCCESS;
}
enum mie_status mie_trait_table_iterator_move_next(
struct mie_trait_table_iterator *it)
{
if (!it->_e) {
return MIE_ERR_NO_ENTRY;
}
it->_e = b_queue_next(it->_e);
if (!it->_e) {
return MIE_ERR_NO_ENTRY;
}
struct unique_trait *trait
= b_unbox(struct unique_trait, it->_e, u_id.e_entry);
it->it_trait = trait->u_trait;
return MIE_SUCCESS;
}

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);
}

View File

@@ -1,9 +1,10 @@
#include <mie/dialect/type.h>
#include <mie/type/type.h> #include <mie/type/type.h>
#include <mie/value.h> #include <mie/value.h>
void mie_value_print(const struct mie_value *value, b_stream *dest) void mie_value_print(const struct mie_value *value, b_stream *dest)
{ {
if (value->v_type && value->v_type->ty_value_print) { if (value->v_type && value->v_type->ty_def->ty_value_print) {
value->v_type->ty_value_print(value->v_type, value, dest); value->v_type->ty_def->ty_value_print(value->v_type, value, dest);
} }
} }

View File

@@ -47,7 +47,7 @@ static int vector_reserve(struct vector *v, size_t new_capacity)
return 0; return 0;
} }
static int vector_push_back(struct vector *v, void *item) static int vector_push_back(struct vector *v, const void *item)
{ {
int err = vector_reserve(v, v->v_count + 1); int err = vector_reserve(v, v->v_count + 1);
if (err != 0) { if (err != 0) {
@@ -108,7 +108,8 @@ static void vector_destroy(struct vector *v, void (*dtor)(void *))
} }
int __mie_vector_push_back( int __mie_vector_push_back(
void **vector, void *item, size_t item_size, size_t *count, size_t *max) void **vector, const void *item, size_t item_size, size_t *count,
size_t *max)
{ {
struct vector v = {}; struct vector v = {};
int err = 0; int err = 0;