mie: move all builtin types (int, float, index, etc) and attributes to the builtin dialect
This commit is contained in:
85
mie/dialect/builtin/attribute/float.c
Normal file
85
mie/dialect/builtin/attribute/float.c
Normal file
@@ -0,0 +1,85 @@
|
||||
#include "../float.h"
|
||||
|
||||
#include <blue/core/bstr.h>
|
||||
#include <mie/attribute/attribute-definition.h>
|
||||
#include <mie/attribute/attribute.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/macros.h>
|
||||
#include <mie/parse/parser.h>
|
||||
#include <mie/print/printer.h>
|
||||
|
||||
static enum mie_status print(
|
||||
const struct mie_attribute *value, struct mie_printer *out)
|
||||
{
|
||||
const struct mie_float *float_val = (const struct mie_float *)value;
|
||||
const struct float_type *float_ty
|
||||
= (const struct float_type *)float_val->f_type;
|
||||
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
|
||||
b_stream_write_string(out->p_stream, "#builtin.float<", NULL);
|
||||
}
|
||||
|
||||
switch (float_ty->f_width) {
|
||||
case MIE_FLOAT_32:
|
||||
b_stream_write_fmt(
|
||||
out->p_stream, NULL, "%f : f%zu", float_val->f_val.v_32,
|
||||
float_ty->f_width);
|
||||
break;
|
||||
case MIE_FLOAT_64:
|
||||
b_stream_write_fmt(
|
||||
out->p_stream, NULL, "%lf : f%zu",
|
||||
float_val->f_val.v_64, float_ty->f_width);
|
||||
break;
|
||||
default:
|
||||
b_stream_write_fmt(
|
||||
out->p_stream, NULL, "NaN : f%zu", float_ty->f_width);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
|
||||
b_stream_write_string(out->p_stream, ">", NULL);
|
||||
}
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status parse(
|
||||
struct mie_parser *ctx, const struct mie_attribute **out)
|
||||
{
|
||||
double value = 0;
|
||||
struct mie_file_span span;
|
||||
|
||||
if (!mie_parser_parse_float(ctx, &value, &span)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const struct mie_type *type = NULL;
|
||||
if (!mie_parser_parse_type(ctx, &type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t width = mie_float_type_get_width(type);
|
||||
if (width == (size_t)-1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct mie_attribute *v
|
||||
= mie_ctx_get_float(mie_parser_get_mie_ctx(ctx), value, width);
|
||||
if (!v) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*out = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
MIE_ATTRIBUTE_DEFINITION_BEGIN(mie_builtin_float, "float")
|
||||
MIE_ATTRIBUTE_DEFINITION_STRUCT(struct mie_float);
|
||||
MIE_ATTRIBUTE_DEFINITION_PRINT(print);
|
||||
MIE_ATTRIBUTE_DEFINITION_PARSE(parse);
|
||||
MIE_ATTRIBUTE_DEFINITION_END()
|
||||
76
mie/dialect/builtin/attribute/int.c
Normal file
76
mie/dialect/builtin/attribute/int.c
Normal file
@@ -0,0 +1,76 @@
|
||||
#include "../int.h"
|
||||
|
||||
#include <blue/core/bstr.h>
|
||||
#include <mie/attribute/attribute-definition.h>
|
||||
#include <mie/attribute/attribute.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/macros.h>
|
||||
#include <mie/parse/parser.h>
|
||||
#include <mie/print/printer.h>
|
||||
|
||||
static enum mie_status print(
|
||||
const struct mie_attribute *value, struct mie_printer *out)
|
||||
{
|
||||
const struct mie_int *int_val = (const struct mie_int *)value;
|
||||
const struct int_type *int_ty = (const struct int_type *)int_val->i_type;
|
||||
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
|
||||
b_stream_write_string(out->p_stream, "#builtin.int<", NULL);
|
||||
}
|
||||
|
||||
if (int_ty->i_width <= 64) {
|
||||
b_stream_write_fmt(
|
||||
out->p_stream, NULL, "%zu : i%zu",
|
||||
int_val->i_val.v_small, int_ty->i_width);
|
||||
} else {
|
||||
b_stream_write_fmt(
|
||||
out->p_stream, NULL, "INF : i%zu", int_ty->i_width);
|
||||
}
|
||||
|
||||
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
|
||||
b_stream_write_string(out->p_stream, ">", NULL);
|
||||
}
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status parse(
|
||||
struct mie_parser *ctx, const struct mie_attribute **out)
|
||||
{
|
||||
long long value = 0;
|
||||
struct mie_file_span span;
|
||||
|
||||
if (!mie_parser_parse_int(ctx, &value, &span)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const struct mie_type *type = NULL;
|
||||
if (!mie_parser_parse_type(ctx, &type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t width = mie_int_type_get_width(type);
|
||||
if (width == (size_t)-1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct mie_attribute *v
|
||||
= mie_ctx_get_int(mie_parser_get_mie_ctx(ctx), value, width);
|
||||
if (!v) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*out = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
MIE_ATTRIBUTE_DEFINITION_BEGIN(mie_builtin_int, "int")
|
||||
MIE_ATTRIBUTE_DEFINITION_STRUCT(struct mie_int);
|
||||
MIE_ATTRIBUTE_DEFINITION_PRINT(print);
|
||||
MIE_ATTRIBUTE_DEFINITION_PARSE(parse);
|
||||
MIE_ATTRIBUTE_DEFINITION_END()
|
||||
@@ -6,12 +6,18 @@
|
||||
struct builtin_dialect {
|
||||
struct mie_dialect d_base;
|
||||
struct mie_string_cache *ctx_strings;
|
||||
struct mie_int_cache *ctx_ints;
|
||||
struct mie_float_cache *ctx_floats;
|
||||
struct mie_index_cache *ctx_indices;
|
||||
};
|
||||
|
||||
static enum mie_status init(struct mie_dialect *d)
|
||||
{
|
||||
struct builtin_dialect *dialect = (struct builtin_dialect *)d;
|
||||
dialect->ctx_strings = mie_string_cache_create();
|
||||
dialect->ctx_ints = mie_int_cache_create();
|
||||
dialect->ctx_floats = mie_float_cache_create();
|
||||
dialect->ctx_indices = mie_index_cache_create();
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -19,9 +25,38 @@ static enum mie_status cleanup(struct mie_dialect *d)
|
||||
{
|
||||
struct builtin_dialect *dialect = (struct builtin_dialect *)d;
|
||||
mie_string_cache_destroy(dialect->ctx_strings);
|
||||
mie_int_cache_destroy(dialect->ctx_ints);
|
||||
mie_float_cache_destroy(dialect->ctx_floats);
|
||||
mie_index_cache_destroy(dialect->ctx_indices);
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
struct mie_attribute *mie_ctx_get_int(
|
||||
struct mie_ctx *ctx, long long val, size_t nr_bits)
|
||||
{
|
||||
struct builtin_dialect *dialect
|
||||
= (struct builtin_dialect *)mie_ctx_get_dialect(ctx, "builtin");
|
||||
if (!dialect) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (struct mie_attribute *)mie_int_cache_get(
|
||||
dialect->ctx_ints, ctx, val, nr_bits);
|
||||
}
|
||||
|
||||
struct mie_attribute *mie_ctx_get_float(
|
||||
struct mie_ctx *ctx, double val, size_t nr_bits)
|
||||
{
|
||||
struct builtin_dialect *dialect
|
||||
= (struct builtin_dialect *)mie_ctx_get_dialect(ctx, "builtin");
|
||||
if (!dialect) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (struct mie_attribute *)mie_float_cache_get(
|
||||
dialect->ctx_floats, ctx, val, nr_bits);
|
||||
}
|
||||
|
||||
struct mie_attribute *mie_ctx_get_string(struct mie_ctx *ctx, const char *s)
|
||||
{
|
||||
struct builtin_dialect *dialect
|
||||
@@ -34,10 +69,27 @@ struct mie_attribute *mie_ctx_get_string(struct mie_ctx *ctx, const char *s)
|
||||
dialect->ctx_strings, ctx, s);
|
||||
}
|
||||
|
||||
struct mie_attribute *mie_ctx_get_index(struct mie_ctx *ctx, size_t val)
|
||||
{
|
||||
struct builtin_dialect *dialect
|
||||
= (struct builtin_dialect *)mie_ctx_get_dialect(ctx, "builtin");
|
||||
if (!dialect) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (struct mie_attribute *)mie_index_cache_get(
|
||||
dialect->ctx_indices, ctx, val);
|
||||
}
|
||||
|
||||
MIE_DIALECT_BEGIN(mie_builtin, struct builtin_dialect, "builtin")
|
||||
MIE_DIALECT_INIT(init);
|
||||
MIE_DIALECT_CLEANUP(cleanup);
|
||||
MIE_DIALECT_ADD_TYPE(mie_builtin_string);
|
||||
MIE_DIALECT_ADD_TYPE(mie_builtin_int);
|
||||
MIE_DIALECT_ADD_TYPE(mie_builtin_float);
|
||||
MIE_DIALECT_ADD_TYPE(mie_builtin_index);
|
||||
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_string);
|
||||
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_int);
|
||||
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_float);
|
||||
MIE_DIALECT_ADD_TRAIT(mie_builtin_isolated_from_above);
|
||||
MIE_DIALECT_END()
|
||||
|
||||
12
mie/dialect/builtin/float.h
Normal file
12
mie/dialect/builtin/float.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef _BUILTIN_FLOAT_H_
|
||||
#define _BUILTIN_FLOAT_H_
|
||||
|
||||
#include <mie/attribute/attribute.h>
|
||||
#include <mie/type/type.h>
|
||||
|
||||
struct float_type {
|
||||
struct mie_type f_base;
|
||||
size_t f_width;
|
||||
};
|
||||
|
||||
#endif
|
||||
81
mie/dialect/builtin/index-cache.c
Normal file
81
mie/dialect/builtin/index-cache.c
Normal file
@@ -0,0 +1,81 @@
|
||||
#include <blue/core/btree.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct index_cache_entry {
|
||||
b_btree_node e_node;
|
||||
struct mie_index e_value;
|
||||
};
|
||||
|
||||
struct mie_index_cache {
|
||||
b_btree c_entries;
|
||||
};
|
||||
|
||||
static B_BTREE_DEFINE_SIMPLE_INSERT(
|
||||
struct index_cache_entry, e_node, e_value.i_value, put_index);
|
||||
static B_BTREE_DEFINE_SIMPLE_GET(
|
||||
struct index_cache_entry, size_t, e_node, e_value.i_value, get_index);
|
||||
|
||||
static struct index_cache_entry *index_cache_entry_create(
|
||||
struct mie_ctx *ctx, size_t val)
|
||||
{
|
||||
struct index_cache_entry *out = malloc(sizeof *out);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(out, 0x0, sizeof *out);
|
||||
|
||||
out->e_value.i_base.a_def
|
||||
= mie_ctx_get_attribute_definition(ctx, "builtin", "index");
|
||||
out->e_value.i_value = val;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
struct mie_index_cache *mie_index_cache_create(void)
|
||||
{
|
||||
struct mie_index_cache *out = malloc(sizeof *out);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(out, 0x0, sizeof *out);
|
||||
return out;
|
||||
}
|
||||
|
||||
void mie_index_cache_destroy(struct mie_index_cache *cache)
|
||||
{
|
||||
b_btree_node *cur = b_btree_first(&cache->c_entries);
|
||||
while (cur) {
|
||||
b_btree_node *next = b_btree_next(cur);
|
||||
b_btree_delete(&cache->c_entries, cur);
|
||||
|
||||
struct index_cache_entry *entry
|
||||
= b_unbox(struct index_cache_entry, cur, e_node);
|
||||
free(entry);
|
||||
|
||||
cur = next;
|
||||
}
|
||||
|
||||
free(cache);
|
||||
}
|
||||
|
||||
struct mie_index *mie_index_cache_get(
|
||||
struct mie_index_cache *cache, struct mie_ctx *ctx, size_t value)
|
||||
{
|
||||
struct index_cache_entry *entry = get_index(&cache->c_entries, value);
|
||||
if (!entry) {
|
||||
entry = index_cache_entry_create(ctx, value);
|
||||
|
||||
if (!entry) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
put_index(&cache->c_entries, entry);
|
||||
}
|
||||
|
||||
return &entry->e_value;
|
||||
}
|
||||
12
mie/dialect/builtin/int.h
Normal file
12
mie/dialect/builtin/int.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef _BUILTIN_INT_H_
|
||||
#define _BUILTIN_INT_H_
|
||||
|
||||
#include <mie/attribute/attribute.h>
|
||||
#include <mie/type/type.h>
|
||||
|
||||
struct int_type {
|
||||
struct mie_type i_base;
|
||||
size_t i_width;
|
||||
};
|
||||
|
||||
#endif
|
||||
80
mie/dialect/builtin/type/float.c
Normal file
80
mie/dialect/builtin/type/float.c
Normal file
@@ -0,0 +1,80 @@
|
||||
#include "../float.h"
|
||||
|
||||
#include <blue/core/bstr.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/macros.h>
|
||||
#include <mie/print/printer.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/type/type.h>
|
||||
|
||||
struct mie_type *mie_ctx_get_float_type(struct mie_ctx *ctx, size_t bit_width)
|
||||
{
|
||||
struct mie_type_definition *type_info
|
||||
= mie_ctx_get_type_definition(ctx, "builtin", "float");
|
||||
if (!type_info) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b_rope rope_i = B_ROPE_CHAR('f'), rope_width = B_ROPE_UINT(bit_width);
|
||||
b_rope type_name;
|
||||
b_rope_concat(&type_name, &rope_i, &rope_width);
|
||||
|
||||
mie_id id;
|
||||
mie_id_init_ns(&id, mie_id_map_get_ns(&ctx->ctx_types), &type_name);
|
||||
|
||||
mie_id *target = mie_id_map_get(&ctx->ctx_types, &id);
|
||||
if (target) {
|
||||
return b_unbox(struct mie_type, target, ty_id);
|
||||
}
|
||||
|
||||
struct float_type *type = (struct float_type *)mie_type_create(type_info);
|
||||
if (!type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
type->f_base.ty_name = b_bstr_fmt("builtin.float<%zu>", bit_width);
|
||||
type->f_base.ty_instance_size = sizeof(struct mie_float);
|
||||
type->f_width = bit_width;
|
||||
|
||||
mie_id_map_put(&ctx->ctx_types, &type->f_base.ty_id, &type_name);
|
||||
return (struct mie_type *)type;
|
||||
}
|
||||
|
||||
size_t mie_float_type_get_width(const struct mie_type *type)
|
||||
{
|
||||
if (strcmp(type->ty_def->ty_parent->d_name, "builtin") != 0) {
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
if (strcmp(type->ty_def->ty_name, "float") != 0) {
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
const struct float_type *float_type = (const struct float_type *)type;
|
||||
return float_type->f_width;
|
||||
}
|
||||
|
||||
static enum mie_status print(const struct mie_type *ty, struct mie_printer *out)
|
||||
{
|
||||
const struct float_type *float_type = (const struct float_type *)ty;
|
||||
b_stream_write_fmt(
|
||||
out->p_stream, NULL,
|
||||
(out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "f%zu" : "!builtin.float<%zu>",
|
||||
float_type->f_width);
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status parse(struct mie_parser *parser, const struct mie_type **out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_TYPE_DEFINITION_BEGIN(mie_builtin_float, "float")
|
||||
// MIE_TYPE_DEFINITION_FLAGS(MIE_TYPE_DEFINITION_PARAMETISED);
|
||||
MIE_TYPE_DEFINITION_STRUCT(struct float_type);
|
||||
MIE_TYPE_DEFINITION_PRINT(print);
|
||||
MIE_TYPE_DEFINITION_PARSE(parse);
|
||||
MIE_TYPE_DEFINITION_END()
|
||||
31
mie/dialect/builtin/type/index.c
Normal file
31
mie/dialect/builtin/type/index.c
Normal file
@@ -0,0 +1,31 @@
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/macros.h>
|
||||
#include <mie/print/printer.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/type/type.h>
|
||||
|
||||
struct index_type {
|
||||
struct mie_type i_base;
|
||||
};
|
||||
|
||||
static void type_init(
|
||||
const struct mie_type_definition *type_info, struct mie_type *type)
|
||||
{
|
||||
type->ty_instance_size = sizeof(struct mie_index);
|
||||
}
|
||||
|
||||
static enum mie_status print(const struct mie_type *ty, struct mie_printer *out)
|
||||
{
|
||||
b_stream_write_string(
|
||||
out->p_stream,
|
||||
(out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "index" : "!builtin.index",
|
||||
NULL);
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_TYPE_DEFINITION_BEGIN(mie_builtin_index, "index")
|
||||
MIE_TYPE_DEFINITION_STRUCT(struct index_type);
|
||||
MIE_TYPE_DEFINITION_INIT(type_init);
|
||||
MIE_TYPE_DEFINITION_PRINT(print);
|
||||
MIE_TYPE_DEFINITION_END()
|
||||
81
mie/dialect/builtin/type/int.c
Normal file
81
mie/dialect/builtin/type/int.c
Normal file
@@ -0,0 +1,81 @@
|
||||
#include "../int.h"
|
||||
|
||||
#include <blue/core/bstr.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/macros.h>
|
||||
#include <mie/print/printer.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/type/type.h>
|
||||
|
||||
struct mie_type *mie_ctx_get_int_type(struct mie_ctx *ctx, size_t bit_width)
|
||||
{
|
||||
struct mie_type_definition *type_info
|
||||
= mie_ctx_get_type_definition(ctx, "builtin", "int");
|
||||
if (!type_info) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b_rope rope_i = B_ROPE_CHAR('i'), rope_width = B_ROPE_UINT(bit_width);
|
||||
b_rope type_name;
|
||||
b_rope_concat(&type_name, &rope_i, &rope_width);
|
||||
|
||||
mie_id id;
|
||||
mie_id_init_ns(&id, mie_id_map_get_ns(&ctx->ctx_types), &type_name);
|
||||
|
||||
mie_id *target = mie_id_map_get(&ctx->ctx_types, &id);
|
||||
if (target) {
|
||||
return b_unbox(struct mie_type, target, ty_id);
|
||||
}
|
||||
|
||||
struct int_type *type = (struct int_type *)mie_type_create(type_info);
|
||||
if (!type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
type->i_base.ty_name = b_bstr_fmt("builtin.int<%zu>", bit_width);
|
||||
type->i_base.ty_instance_size = sizeof(struct mie_int);
|
||||
type->i_width = bit_width;
|
||||
|
||||
mie_id_map_put(&ctx->ctx_types, &type->i_base.ty_id, &type_name);
|
||||
return (struct mie_type *)type;
|
||||
}
|
||||
|
||||
size_t mie_int_type_get_width(const struct mie_type *type)
|
||||
{
|
||||
if (strcmp(type->ty_def->ty_parent->d_name, "builtin") != 0) {
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
if (strcmp(type->ty_def->ty_name, "int") != 0) {
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
const struct int_type *int_type = (const struct int_type *)type;
|
||||
return int_type->i_width;
|
||||
}
|
||||
|
||||
static enum mie_status print(const struct mie_type *ty, struct mie_printer *out)
|
||||
{
|
||||
const struct int_type *int_type = (const struct int_type *)ty;
|
||||
b_stream_write_fmt(
|
||||
out->p_stream, NULL,
|
||||
(out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "i%zu"
|
||||
: "!builtin.int<%zu>",
|
||||
int_type->i_width);
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status parse(struct mie_parser *parser, const struct mie_type **out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_TYPE_DEFINITION_BEGIN(mie_builtin_int, "int")
|
||||
// MIE_TYPE_DEFINITION_FLAGS(MIE_TYPE_DEFINITION_PARAMETISED);
|
||||
MIE_TYPE_DEFINITION_STRUCT(struct int_type);
|
||||
MIE_TYPE_DEFINITION_PRINT(print);
|
||||
MIE_TYPE_DEFINITION_PARSE(parse);
|
||||
MIE_TYPE_DEFINITION_END()
|
||||
Reference in New Issue
Block a user