Implements C transpiler for unpack function.
This commit is contained in:
parent
b96fbb6eb2
commit
899aceb118
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
*.swp
|
*.swp
|
||||||
/.build
|
/.build
|
||||||
|
/test
|
||||||
|
@ -24,10 +24,11 @@ add_executable(biner)
|
|||||||
target_sources(biner
|
target_sources(biner
|
||||||
PRIVATE
|
PRIVATE
|
||||||
main.c
|
main.c
|
||||||
|
transpile_c.c
|
||||||
tree.c
|
tree.c
|
||||||
${BISON_biner-parser_OUTPUTS}
|
${BISON_biner-parser_OUTPUTS}
|
||||||
${FLEX_biner-scanner_OUTPUTS}
|
${FLEX_biner-scanner_OUTPUTS}
|
||||||
PUBLIC
|
PUBLIC
|
||||||
zone.h
|
c/zone.h
|
||||||
)
|
)
|
||||||
target_include_directories(biner PRIVATE . ${CMAKE_CURRENT_BINARY_DIR})
|
target_include_directories(biner PRIVATE . ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
4
TODO.TXT
4
TODO.TXT
@ -8,5 +8,7 @@ X enum support
|
|||||||
X constant support
|
X constant support
|
||||||
X conditional switching support
|
X conditional switching support
|
||||||
X union support
|
X union support
|
||||||
transpiler for C
|
X C transpiler for unpacking
|
||||||
|
C transpiler for packing
|
||||||
|
add bitmanip operators
|
||||||
release 1.0.0
|
release 1.0.0
|
||||||
|
2
biner.l
2
biner.l
@ -6,7 +6,7 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include "./tree.h"
|
#include "./tree.h"
|
||||||
#include "./zone.h"
|
#include "./c/zone.h"
|
||||||
|
|
||||||
#include "generated/biner.y.h"
|
#include "generated/biner.y.h"
|
||||||
|
|
||||||
|
15
biner.y
15
biner.y
@ -8,7 +8,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "./tree.h"
|
#include "./tree.h"
|
||||||
#include "./zone.h"
|
#include "./c/zone.h"
|
||||||
|
|
||||||
#define ctx (biner_tree_parse_context_)
|
#define ctx (biner_tree_parse_context_)
|
||||||
|
|
||||||
@ -248,8 +248,13 @@ unqualified_struct_member_type
|
|||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
t->name = BINER_TREE_STRUCT_MEMBER_TYPE_NAME_USER_DECL;
|
if (ref(biner_tree_decl_t, decl)->type == BINER_TREE_DECL_TYPE_STRUCT) {
|
||||||
t->decl = decl;
|
t->name = BINER_TREE_STRUCT_MEMBER_TYPE_NAME_USER_DECL;
|
||||||
|
t->decl = decl;
|
||||||
|
} else {
|
||||||
|
yyerrorf("'%s' is not struct", ref(char, $1));
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -303,7 +308,7 @@ mul_expr
|
|||||||
unary_expr
|
unary_expr
|
||||||
: operand
|
: operand
|
||||||
| '!' operand {
|
| '!' operand {
|
||||||
$$ = create_operator_($2, BINER_TREE_EXPR_TYPE_OPERATOR_NOT, 0);
|
$$ = create_operator_(0, BINER_TREE_EXPR_TYPE_OPERATOR_NOT, $2);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -443,7 +448,7 @@ static inline bool unstringify_struct_member_type_name_(
|
|||||||
biner_tree_struct_member_type_name_t* name,
|
biner_tree_struct_member_type_name_t* name,
|
||||||
biner_zone_ptr(char) str) {
|
biner_zone_ptr(char) str) {
|
||||||
for (size_t i = 0; i < BINER_TREE_STRUCT_MEMBER_TYPE_NAME_MAX_; ++i) {
|
for (size_t i = 0; i < BINER_TREE_STRUCT_MEMBER_TYPE_NAME_MAX_; ++i) {
|
||||||
const char* item = biner_tree_struct_member_type_name_string_map[i];
|
const char* item = biner_tree_struct_member_type_name_meta_map[i].name;
|
||||||
if (item != NULL && strcmp(ref(char, str), item) == 0) {
|
if (item != NULL && strcmp(ref(char, str), item) == 0) {
|
||||||
*name = (biner_tree_struct_member_type_name_t) i;
|
*name = (biner_tree_struct_member_type_name_t) i;
|
||||||
return true;
|
return true;
|
||||||
|
36
c/unpack.h
Normal file
36
c/unpack.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
|
# define unpack_Nbit_(N) \
|
||||||
|
static inline void biner_unpack_l##N(int##N##_t* v, uint8_t c, size_t s) { \
|
||||||
|
assert(s < N/8); \
|
||||||
|
*v = (*v & (0xff << (s*8))) | (c << (s*8)); \
|
||||||
|
} \
|
||||||
|
static inline void biner_unpack_b##N(int##N##_t* v, uint8_t c, size_t s) { \
|
||||||
|
assert(s < N/8); \
|
||||||
|
biner_unpack_l##N(v, c, N/8-s-1); \
|
||||||
|
}
|
||||||
|
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||||
|
# define unpack_Nbit_(N) \
|
||||||
|
static inline void biner_unpack_b##N(int##N##_t* v, uint8_t c, size_t s) { \
|
||||||
|
assert(s < N/8); \
|
||||||
|
*v = (*v & (0xff << (s*8))) | (c << (s*8)); \
|
||||||
|
} \
|
||||||
|
static inline void biner_unpack_l##N(int##N##_t* v, uint8_t c, size_t s) { \
|
||||||
|
assert(s < N/8); \
|
||||||
|
biner_unpack_b##N(v, c, N/8-s-1); \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# error "byte order unknown"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unpack_Nbit_(8);
|
||||||
|
unpack_Nbit_(16);
|
||||||
|
unpack_Nbit_(32);
|
||||||
|
unpack_Nbit_(64);
|
||||||
|
|
||||||
|
#undef unpack_Nbit_
|
70
main.c
70
main.c
@ -1,77 +1,17 @@
|
|||||||
#include <assert.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "./transpile.h"
|
||||||
#include "./tree.h"
|
#include "./tree.h"
|
||||||
|
|
||||||
static inline void print_enum_(
|
|
||||||
const uint8_t* zone, const biner_tree_decl_t* decl) {
|
|
||||||
assert(zone != NULL);
|
|
||||||
assert(decl != NULL);
|
|
||||||
|
|
||||||
printf("enum %s:\n", zone + decl->name);
|
|
||||||
const biner_tree_enum_member_t* member =
|
|
||||||
(const biner_tree_enum_member_t*) (zone + decl->enum_);
|
|
||||||
while ((uintptr_t) member != (uintptr_t) zone) {
|
|
||||||
printf(" %s\n", zone + member->name);
|
|
||||||
member = (const biner_tree_enum_member_t*) (zone + member->prev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void print_struct_(
|
|
||||||
const uint8_t* zone, const biner_tree_decl_t* decl) {
|
|
||||||
assert(zone != NULL);
|
|
||||||
assert(decl != NULL);
|
|
||||||
|
|
||||||
printf("struct %s:\n", zone + decl->name);
|
|
||||||
const biner_tree_struct_member_t* member =
|
|
||||||
(const biner_tree_struct_member_t*) (zone + decl->struct_);
|
|
||||||
while ((uintptr_t) member != (uintptr_t) zone) {
|
|
||||||
printf(" %2zu ", member->index);
|
|
||||||
const biner_tree_struct_member_type_t* type =
|
|
||||||
(const biner_tree_struct_member_type_t*) (zone + member->type);
|
|
||||||
if (type->name == BINER_TREE_STRUCT_MEMBER_TYPE_NAME_USER_DECL) {
|
|
||||||
const biner_tree_decl_t* decl =
|
|
||||||
(const biner_tree_decl_t*) (zone + type->decl);
|
|
||||||
printf("%8s ", zone + decl->name);
|
|
||||||
} else {
|
|
||||||
printf("%8s ",
|
|
||||||
biner_tree_struct_member_type_name_string_map[type->name]);
|
|
||||||
}
|
|
||||||
if (member->condition == 0) {
|
|
||||||
printf("%s", zone + member->name);
|
|
||||||
} else {
|
|
||||||
printf("(%s)", zone + member->name);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
member = (const biner_tree_struct_member_t*) (zone + member->prev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
const uint8_t* zone = biner_tree_parse(stdin);
|
const uint8_t* zone = biner_tree_parse(stdin);
|
||||||
if (zone == NULL) return EXIT_FAILURE;
|
if (zone == NULL) return EXIT_FAILURE;
|
||||||
|
|
||||||
const biner_tree_root_t* root = (const biner_tree_root_t*) zone;
|
biner_transpile_c(&(biner_transpile_param_t) {
|
||||||
|
.zone = zone,
|
||||||
const biner_tree_decl_t* decl =
|
.dst = stdout,
|
||||||
(const biner_tree_decl_t*) (zone + root->decls);
|
});
|
||||||
while ((uintptr_t) decl != (uintptr_t) zone) {
|
|
||||||
switch (decl->type) {
|
|
||||||
case BINER_TREE_DECL_TYPE_CONST:
|
|
||||||
printf("const %s\n", zone + decl->name);
|
|
||||||
break;
|
|
||||||
case BINER_TREE_DECL_TYPE_ENUM:
|
|
||||||
print_enum_(zone, decl);
|
|
||||||
break;
|
|
||||||
case BINER_TREE_DECL_TYPE_STRUCT:
|
|
||||||
print_struct_(zone, decl);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
;
|
|
||||||
}
|
|
||||||
decl = (const biner_tree_decl_t*) (zone + decl->prev);
|
|
||||||
}
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
15
transpile.h
Normal file
15
transpile.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
typedef struct biner_transpile_param_t {
|
||||||
|
const uint8_t* zone;
|
||||||
|
FILE* dst;
|
||||||
|
} biner_transpile_param_t;
|
||||||
|
|
||||||
|
bool
|
||||||
|
biner_transpile_c(
|
||||||
|
const biner_transpile_param_t* p
|
||||||
|
);
|
500
transpile_c.c
Normal file
500
transpile_c.c
Normal file
@ -0,0 +1,500 @@
|
|||||||
|
#include "./transpile.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "./tree.h"
|
||||||
|
|
||||||
|
#define PACK_CONTEXT_SUFFIX_ "_pack_context_t"
|
||||||
|
#define UNPACK_CONTEXT_SUFFIX_ "_unpack_context_t"
|
||||||
|
|
||||||
|
typedef struct struct_member_type_name_meta_t {
|
||||||
|
const char* func;
|
||||||
|
const char* type;
|
||||||
|
} struct_member_type_name_meta_t;
|
||||||
|
|
||||||
|
static const struct_member_type_name_meta_t struct_member_type_name_meta_map_
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_MAX_] = {
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LU8] = {"l8", "uint8_t"},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LU16] = {"l16", "uint16_t"},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LU32] = {"l32", "uint32_t"},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LU64] = {"l64", "uint64_t"},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LI8] = {"l8", "int8_t"},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LI16] = {"l16", "int16_t"},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LI32] = {"l32", "int32_t"},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LI64] = {"l64", "int64_t"},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BU8] = {"b8", "uint8_t"},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BU16] = {"b16", "uint16_t"},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BU32] = {"b32", "uint32_t"},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BU64] = {"b64", "uint64_t"},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI8] = {"b8", "int8_t"},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI16] = {"b16", "int16_t"},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI32] = {"b32", "int32_t"},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI64] = {"b64", "int64_t"},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_F16] = {"f16", "float"},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_F32] = {"f32", "float"},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_F64] = {"f64", "double"},
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct struct_member_info_t {
|
||||||
|
const biner_transpile_param_t* p;
|
||||||
|
const biner_tree_struct_member_t* m;
|
||||||
|
const biner_tree_struct_member_type_t* t;
|
||||||
|
|
||||||
|
bool union_begin;
|
||||||
|
bool union_end;
|
||||||
|
bool union_member;
|
||||||
|
size_t offset;
|
||||||
|
} struct_member_info_t;
|
||||||
|
|
||||||
|
typedef void (*struct_member_each_func_t)(const struct_member_info_t*);
|
||||||
|
|
||||||
|
static size_t struct_member_each_(
|
||||||
|
const biner_transpile_param_t* p,
|
||||||
|
const biner_tree_struct_member_t* m,
|
||||||
|
struct_member_each_func_t f,
|
||||||
|
size_t next_index) {
|
||||||
|
assert(p != NULL);
|
||||||
|
assert(m != NULL);
|
||||||
|
assert(f != NULL);
|
||||||
|
|
||||||
|
struct_member_info_t info = {
|
||||||
|
.p = p,
|
||||||
|
.m = m,
|
||||||
|
.t = (const biner_tree_struct_member_type_t*) (p->zone+m->type),
|
||||||
|
.union_begin = (m->index == next_index),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (m->prev != 0) {
|
||||||
|
const biner_tree_struct_member_t* prev =
|
||||||
|
(const biner_tree_struct_member_t*) (p->zone+m->prev);
|
||||||
|
if (prev->index == m->index) {
|
||||||
|
info.union_end = !info.union_begin;
|
||||||
|
info.union_begin = false;
|
||||||
|
info.union_member = true;
|
||||||
|
}
|
||||||
|
info.offset = struct_member_each_(p, prev, f, m->index);
|
||||||
|
}
|
||||||
|
if (info.union_begin) info.union_member = true;
|
||||||
|
|
||||||
|
const size_t size =
|
||||||
|
biner_tree_struct_member_type_name_meta_map[info.t->name].size;
|
||||||
|
f(&info);
|
||||||
|
return info.offset + size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void print_fixed_decl_name_(
|
||||||
|
const biner_transpile_param_t* p, const char* name) {
|
||||||
|
assert(p != NULL);
|
||||||
|
assert(name != NULL);
|
||||||
|
|
||||||
|
const char* end = name;
|
||||||
|
while (*end) ++end;
|
||||||
|
if (name+2 <= end && strcmp(end-2, "_t") == 0) end -= 2;
|
||||||
|
fprintf(p->dst, "%.*s", (int) (end-name), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void print_typedef_header_(
|
||||||
|
const biner_transpile_param_t* p,
|
||||||
|
const char* kind,
|
||||||
|
const char* type,
|
||||||
|
const char* name) {
|
||||||
|
assert(p != NULL);
|
||||||
|
assert(kind != NULL);
|
||||||
|
assert(type != NULL);
|
||||||
|
assert(name != NULL);
|
||||||
|
|
||||||
|
fprintf(p->dst, "typedef %s ", kind);
|
||||||
|
print_fixed_decl_name_(p, type);
|
||||||
|
fprintf(p->dst, "%s { ", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void print_typedef_footer_(
|
||||||
|
const biner_transpile_param_t* p,
|
||||||
|
const char* type,
|
||||||
|
const char* name) {
|
||||||
|
assert(p != NULL);
|
||||||
|
assert(type != NULL);
|
||||||
|
assert(name != NULL);
|
||||||
|
|
||||||
|
fprintf(p->dst, "} ");
|
||||||
|
print_fixed_decl_name_(p, type);
|
||||||
|
fprintf(p->dst, "%s;\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void print_func_header_(
|
||||||
|
const biner_transpile_param_t* p,
|
||||||
|
const char* ret,
|
||||||
|
const char* type,
|
||||||
|
const char* name) {
|
||||||
|
assert(p != NULL);
|
||||||
|
assert(type != NULL);
|
||||||
|
assert(name != NULL);
|
||||||
|
|
||||||
|
fprintf(p->dst, "static inline %s ", ret);
|
||||||
|
print_fixed_decl_name_(p, type);
|
||||||
|
fprintf(p->dst, "%s(", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_struct_member_reference_(
|
||||||
|
const biner_transpile_param_t* p,
|
||||||
|
const biner_tree_struct_member_reference_t* r) {
|
||||||
|
assert(p != NULL);
|
||||||
|
assert(r != NULL);
|
||||||
|
|
||||||
|
if (r->prev != 0) {
|
||||||
|
print_struct_member_reference_(
|
||||||
|
p, (const biner_tree_struct_member_reference_t*) (p->zone+r->prev));
|
||||||
|
}
|
||||||
|
const biner_tree_struct_member_t* m =
|
||||||
|
(const biner_tree_struct_member_t*) (p->zone+r->member);
|
||||||
|
fprintf(p->dst, "%s", p->zone+m->name);
|
||||||
|
if (r->prev != 0) fprintf(p->dst, ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_expr_(
|
||||||
|
const biner_transpile_param_t* p, const biner_tree_expr_t* e) {
|
||||||
|
assert(p != NULL);
|
||||||
|
assert(e != NULL);
|
||||||
|
|
||||||
|
# define print_operator_(op) do { \
|
||||||
|
if (e->operands.l) { \
|
||||||
|
print_expr_(p, (const biner_tree_expr_t*) (p->zone+e->operands.l)); \
|
||||||
|
} \
|
||||||
|
fprintf(p->dst, op); \
|
||||||
|
if (e->operands.r) { \
|
||||||
|
print_expr_(p, (const biner_tree_expr_t*) (p->zone+e->operands.r)); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
fprintf(p->dst, "(");
|
||||||
|
|
||||||
|
switch (e->type) {
|
||||||
|
case BINER_TREE_EXPR_TYPE_OPERAND_INTEGER:
|
||||||
|
fprintf(p->dst, "%"PRIi64, e->i);
|
||||||
|
break;
|
||||||
|
case BINER_TREE_EXPR_TYPE_OPERAND_REFERENCE:
|
||||||
|
fprintf(p->dst, "s->");
|
||||||
|
print_struct_member_reference_(
|
||||||
|
p, (const biner_tree_struct_member_reference_t*) (p->zone+e->r));
|
||||||
|
break;
|
||||||
|
case BINER_TREE_EXPR_TYPE_OPERATOR_EQUAL:
|
||||||
|
print_operator_("==");
|
||||||
|
break;
|
||||||
|
case BINER_TREE_EXPR_TYPE_OPERATOR_NEQUAL:
|
||||||
|
print_operator_("!=");
|
||||||
|
break;
|
||||||
|
case BINER_TREE_EXPR_TYPE_OPERATOR_GREATER_EQUAL:
|
||||||
|
print_operator_(">=");
|
||||||
|
break;
|
||||||
|
case BINER_TREE_EXPR_TYPE_OPERATOR_LESS_EQUAL:
|
||||||
|
print_operator_("<=");
|
||||||
|
break;
|
||||||
|
case BINER_TREE_EXPR_TYPE_OPERATOR_GREATER:
|
||||||
|
print_operator_(">");
|
||||||
|
break;
|
||||||
|
case BINER_TREE_EXPR_TYPE_OPERATOR_LESS:
|
||||||
|
print_operator_("<");
|
||||||
|
break;
|
||||||
|
case BINER_TREE_EXPR_TYPE_OPERATOR_NOT:
|
||||||
|
print_operator_("!");
|
||||||
|
break;
|
||||||
|
case BINER_TREE_EXPR_TYPE_OPERATOR_ADD:
|
||||||
|
print_operator_("+");
|
||||||
|
break;
|
||||||
|
case BINER_TREE_EXPR_TYPE_OPERATOR_SUB:
|
||||||
|
print_operator_("-");
|
||||||
|
break;
|
||||||
|
case BINER_TREE_EXPR_TYPE_OPERATOR_MUL:
|
||||||
|
print_operator_("*");
|
||||||
|
break;
|
||||||
|
case BINER_TREE_EXPR_TYPE_OPERATOR_DIV:
|
||||||
|
print_operator_("/");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(p->dst, ")");
|
||||||
|
|
||||||
|
# undef print_operator_
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_enum_member_decls_(
|
||||||
|
const biner_transpile_param_t* p,
|
||||||
|
const biner_tree_enum_member_t* m) {
|
||||||
|
assert(p != NULL);
|
||||||
|
assert(m != NULL);
|
||||||
|
|
||||||
|
if (m->prev != 0) {
|
||||||
|
print_enum_member_decls_(
|
||||||
|
p, (const biner_tree_enum_member_t*) (p->zone+m->prev));
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(p->dst, "%s=", p->zone+m->name);
|
||||||
|
print_expr_(p, (const biner_tree_expr_t*) (p->zone+m->expr));
|
||||||
|
fprintf(p->dst, ",");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_enum_member_validation_code_(
|
||||||
|
const biner_transpile_param_t* p,
|
||||||
|
const biner_tree_enum_member_t* m) {
|
||||||
|
assert(p != NULL);
|
||||||
|
assert(m != NULL);
|
||||||
|
|
||||||
|
fprintf(p->dst, "return true");
|
||||||
|
while ((uintptr_t*) m != (uintptr_t*) p->zone) {
|
||||||
|
fprintf(p->dst, " && v == %s", p->zone+m->name);
|
||||||
|
m = (const biner_tree_enum_member_t*) (p->zone+m->prev);
|
||||||
|
}
|
||||||
|
fprintf(p->dst, ";");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_struct_member_type_name_(
|
||||||
|
const biner_transpile_param_t* p,
|
||||||
|
const biner_tree_struct_member_type_t* t) {
|
||||||
|
assert(p != NULL);
|
||||||
|
assert(t != NULL);
|
||||||
|
|
||||||
|
if (t->name == BINER_TREE_STRUCT_MEMBER_TYPE_NAME_USER_DECL) {
|
||||||
|
const biner_tree_decl_t* d = (const biner_tree_decl_t*) (p->zone+t->decl);
|
||||||
|
print_fixed_decl_name_(p, (const char*) (p->zone+d->name));
|
||||||
|
fprintf(p->dst, "_t");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* name = struct_member_type_name_meta_map_[t->name].type;
|
||||||
|
assert(name != NULL);
|
||||||
|
fprintf(p->dst, "%s", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_struct_member_decl_(const struct_member_info_t* info) {
|
||||||
|
assert(info != NULL);
|
||||||
|
|
||||||
|
if (info->union_begin) fprintf(info->p->dst, "union { ");
|
||||||
|
|
||||||
|
print_struct_member_type_name_(info->p, info->t);
|
||||||
|
fprintf(info->p->dst, " ");
|
||||||
|
|
||||||
|
switch (info->t->qualifier) {
|
||||||
|
case BINER_TREE_STRUCT_MEMBER_TYPE_QUALIFIER_NONE:
|
||||||
|
fprintf(info->p->dst, "%s", info->p->zone+info->m->name);
|
||||||
|
break;
|
||||||
|
case BINER_TREE_STRUCT_MEMBER_TYPE_QUALIFIER_STATIC_ARRAY:
|
||||||
|
fprintf(info->p->dst, "%s[", info->p->zone+info->m->name);
|
||||||
|
print_expr_(
|
||||||
|
info->p, (const biner_tree_expr_t*) (info->p->zone+info->t->expr));
|
||||||
|
fprintf(info->p->dst, "]");
|
||||||
|
break;
|
||||||
|
case BINER_TREE_STRUCT_MEMBER_TYPE_QUALIFIER_DYNAMIC_ARRAY:
|
||||||
|
fprintf(info->p->dst, "*%s", info->p->zone+info->m->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fprintf(info->p->dst, "; ");
|
||||||
|
if (info->union_end) fprintf(info->p->dst, "}; ");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_struct_member_context_struct_(
|
||||||
|
const biner_transpile_param_t* p,
|
||||||
|
const biner_tree_struct_member_t* m,
|
||||||
|
const char* suffix) {
|
||||||
|
assert(p != NULL);
|
||||||
|
assert(m != NULL);
|
||||||
|
|
||||||
|
fprintf(p->dst, "size_t step; ");
|
||||||
|
fprintf(p->dst, "size_t count; ");
|
||||||
|
fprintf(p->dst, "size_t count_max; ");
|
||||||
|
fprintf(p->dst, "size_t byte; ");
|
||||||
|
|
||||||
|
fprintf(p->dst, "union { ");
|
||||||
|
while ((uintptr_t*) m != (uintptr_t*) p->zone) {
|
||||||
|
const biner_tree_struct_member_type_t* t =
|
||||||
|
(const biner_tree_struct_member_type_t*) (p->zone+m->type);
|
||||||
|
if (t->name == BINER_TREE_STRUCT_MEMBER_TYPE_NAME_USER_DECL) {
|
||||||
|
const biner_tree_decl_t* d = (const biner_tree_decl_t*) (p->zone+t->decl);
|
||||||
|
print_fixed_decl_name_(p, (const char*) (p->zone+d->name));
|
||||||
|
fprintf(p->dst, "%s %s; ", suffix, p->zone+m->name);
|
||||||
|
}
|
||||||
|
m = (const biner_tree_struct_member_t*) (p->zone+m->prev);
|
||||||
|
}
|
||||||
|
fprintf(p->dst, "} subctx; ");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_struct_member_unpack_code_each_(
|
||||||
|
const struct_member_info_t* info) {
|
||||||
|
assert(info != NULL);
|
||||||
|
|
||||||
|
const char* name = (const char*) (info->p->zone+info->m->name);
|
||||||
|
|
||||||
|
if (!info->union_member || info->union_begin) {
|
||||||
|
fprintf(info->p->dst, "init%zu: ", info->m->index);
|
||||||
|
fprintf(info->p->dst, "++ctx->step; ctx->byte = 0; ");
|
||||||
|
|
||||||
|
switch (info->t->qualifier) {
|
||||||
|
case BINER_TREE_STRUCT_MEMBER_TYPE_QUALIFIER_DYNAMIC_ARRAY:
|
||||||
|
fprintf(info->p->dst, "ctx->count_max = ");
|
||||||
|
print_expr_(
|
||||||
|
info->p, (const biner_tree_expr_t*) (info->p->zone+info->t->expr));
|
||||||
|
fprintf(info->p->dst, "; ");
|
||||||
|
fprintf(info->p->dst,
|
||||||
|
"s->%s = malloc(sizeof(*s->%s)*ctx->count_max); ",
|
||||||
|
name, name);
|
||||||
|
fprintf(info->p->dst, "ctx->count = 0; ");
|
||||||
|
break;
|
||||||
|
case BINER_TREE_STRUCT_MEMBER_TYPE_QUALIFIER_STATIC_ARRAY:
|
||||||
|
fprintf(info->p->dst, "ctx->count = 0; ");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(info->p->dst, "body%zu: ", info->m->index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info->m->condition != 0) {
|
||||||
|
fprintf(info->p->dst, "if (");
|
||||||
|
print_expr_(
|
||||||
|
info->p, (const biner_tree_expr_t*) (info->p->zone+info->m->condition));
|
||||||
|
fprintf(info->p->dst, ") {");
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* suffix = "";
|
||||||
|
switch (info->t->qualifier) {
|
||||||
|
case BINER_TREE_STRUCT_MEMBER_TYPE_QUALIFIER_DYNAMIC_ARRAY:
|
||||||
|
case BINER_TREE_STRUCT_MEMBER_TYPE_QUALIFIER_STATIC_ARRAY:
|
||||||
|
suffix = "[ctx->count]";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info->t->name == BINER_TREE_STRUCT_MEMBER_TYPE_NAME_USER_DECL) {
|
||||||
|
const biner_tree_decl_t* d =
|
||||||
|
(const biner_tree_decl_t*) (info->p->zone+info->t->decl);
|
||||||
|
|
||||||
|
fprintf(info->p->dst, "if (");
|
||||||
|
print_fixed_decl_name_(info->p, (const char*) (info->p->zone+d->name));
|
||||||
|
fprintf(info->p->dst, "_unpack(&ctx->subctx.%s, &s->%s%s, c)) { ", name, name, suffix);
|
||||||
|
} else {
|
||||||
|
const char* func = struct_member_type_name_meta_map_[info->t->name].func;
|
||||||
|
fprintf(info->p->dst,
|
||||||
|
"biner_unpack_%s(&s->%s%s, c, ctx->byte); ", func, name, suffix);
|
||||||
|
const size_t sz = biner_tree_struct_member_type_name_meta_map[info->t->name].size;
|
||||||
|
fprintf(info->p->dst, "if (++ctx->byte >= %zu) { ", sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (info->t->qualifier) {
|
||||||
|
case BINER_TREE_STRUCT_MEMBER_TYPE_QUALIFIER_DYNAMIC_ARRAY:
|
||||||
|
fprintf(info->p->dst,
|
||||||
|
"if (++ctx->count >= ctx->count_max) goto NEXT; ctx->byte = 0; ");
|
||||||
|
break;
|
||||||
|
case BINER_TREE_STRUCT_MEMBER_TYPE_QUALIFIER_STATIC_ARRAY:
|
||||||
|
fprintf(info->p->dst, "if (++ctx->count >= ");
|
||||||
|
print_expr_(
|
||||||
|
info->p, (const biner_tree_expr_t*) (info->p->zone+info->t->expr));
|
||||||
|
fprintf(info->p->dst, ") goto NEXT; ctx->byte = 0; ");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(info->p->dst, "goto NEXT; ");
|
||||||
|
}
|
||||||
|
fprintf(info->p->dst, "} return false; ");
|
||||||
|
|
||||||
|
if (info->m->condition != 0) {
|
||||||
|
fprintf(info->p->dst, "} ");
|
||||||
|
if (!info->union_member || info->union_end) {
|
||||||
|
fprintf(info->p->dst, "goto NEXT; ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_struct_member_unpack_code_(
|
||||||
|
const biner_transpile_param_t* p, const biner_tree_struct_member_t* m) {
|
||||||
|
assert(p != NULL);
|
||||||
|
assert(m != NULL);
|
||||||
|
|
||||||
|
fprintf(p->dst, "static const void* const steps_[] = { ");
|
||||||
|
for (size_t i = 0; i <= m->index; ++i) {
|
||||||
|
fprintf(p->dst, "&&init%zu, &&body%zu, ", i, i);
|
||||||
|
}
|
||||||
|
fprintf(p->dst, "}; ");
|
||||||
|
|
||||||
|
fprintf(p->dst,
|
||||||
|
"if (ctx->step >= sizeof(steps_)/sizeof(steps_[0])) return true; ");
|
||||||
|
fprintf(p->dst, "goto *steps_[ctx->step]; ");
|
||||||
|
|
||||||
|
struct_member_each_(p, m, print_struct_member_unpack_code_each_, SIZE_MAX);
|
||||||
|
|
||||||
|
fprintf(p->dst, "NEXT: ");
|
||||||
|
fprintf(p->dst, "return ++ctx->step >= sizeof(steps_)/sizeof(steps_[0]); ");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_decls_(
|
||||||
|
const biner_transpile_param_t* p, const biner_tree_decl_t* d) {
|
||||||
|
assert(p != NULL);
|
||||||
|
assert(d != NULL);
|
||||||
|
|
||||||
|
if (d->prev != 0) {
|
||||||
|
print_decls_(p, (const biner_tree_decl_t*) (p->zone+d->prev));
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* name = (const char*) (p->zone+d->name);
|
||||||
|
|
||||||
|
switch (d->type) {
|
||||||
|
case BINER_TREE_DECL_TYPE_CONST: {
|
||||||
|
const biner_tree_expr_t* body =
|
||||||
|
(const biner_tree_expr_t*) (p->zone+d->const_);
|
||||||
|
|
||||||
|
fprintf(p->dst, "#define %s (", name);
|
||||||
|
print_expr_(p, body);
|
||||||
|
fprintf(p->dst, ")\n");
|
||||||
|
} break;
|
||||||
|
case BINER_TREE_DECL_TYPE_ENUM: {
|
||||||
|
const biner_tree_enum_member_t* body =
|
||||||
|
(const biner_tree_enum_member_t*) (p->zone+d->enum_);
|
||||||
|
|
||||||
|
print_typedef_header_(p, "enum", name, "_t");
|
||||||
|
print_enum_member_decls_(p, body);
|
||||||
|
print_typedef_footer_(p, name, "_t");
|
||||||
|
|
||||||
|
print_func_header_(p, "bool", name, "_validate");
|
||||||
|
fprintf(p->dst, "uintmax_t v) { ");
|
||||||
|
print_enum_member_validation_code_(p, body);
|
||||||
|
fprintf(p->dst, "}\n");
|
||||||
|
} break;
|
||||||
|
case BINER_TREE_DECL_TYPE_STRUCT: {
|
||||||
|
const biner_tree_struct_member_t* body =
|
||||||
|
(const biner_tree_struct_member_t*) (p->zone+d->struct_);
|
||||||
|
|
||||||
|
print_typedef_header_(p, "struct", name, "_t");
|
||||||
|
struct_member_each_(p, body, print_struct_member_decl_, SIZE_MAX);
|
||||||
|
print_typedef_footer_(p, name, "_t");
|
||||||
|
|
||||||
|
print_typedef_header_(p, "struct", name, PACK_CONTEXT_SUFFIX_);
|
||||||
|
print_struct_member_context_struct_(p, body, PACK_CONTEXT_SUFFIX_);
|
||||||
|
print_typedef_footer_(p, name, PACK_CONTEXT_SUFFIX_);
|
||||||
|
|
||||||
|
print_typedef_header_(p, "struct", name, UNPACK_CONTEXT_SUFFIX_);
|
||||||
|
print_struct_member_context_struct_(p, body, UNPACK_CONTEXT_SUFFIX_);
|
||||||
|
print_typedef_footer_(p, name, UNPACK_CONTEXT_SUFFIX_);
|
||||||
|
|
||||||
|
print_func_header_(p, "bool", name, "_unpack");
|
||||||
|
print_fixed_decl_name_(p, name);
|
||||||
|
fprintf(p->dst, "_unpack_context_t* ctx, ");
|
||||||
|
print_fixed_decl_name_(p, name);
|
||||||
|
fprintf(p->dst, "_t* s, ");
|
||||||
|
fprintf(p->dst, "uint8_t c) { ");
|
||||||
|
print_struct_member_unpack_code_(p, body);
|
||||||
|
fprintf(p->dst, "}\n");
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool biner_transpile_c(const biner_transpile_param_t* p) {
|
||||||
|
assert(p != NULL);
|
||||||
|
|
||||||
|
const biner_tree_root_t* root = (const biner_tree_root_t*) p->zone;
|
||||||
|
print_decls_(p, (const biner_tree_decl_t*) (p->zone+root->decls));
|
||||||
|
return true;
|
||||||
|
}
|
34
tree.c
34
tree.c
@ -8,22 +8,32 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "./zone.h"
|
#include "./c/zone.h"
|
||||||
|
|
||||||
#include "generated/biner.y.h"
|
#include "generated/biner.y.h"
|
||||||
|
|
||||||
const char* const biner_tree_struct_member_type_name_string_map
|
const biner_tree_struct_member_type_name_meta_t
|
||||||
|
biner_tree_struct_member_type_name_meta_map
|
||||||
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_MAX_] = {
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_MAX_] = {
|
||||||
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_UINT8] = "uint8_t",
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LU8] = {"lu8", 1},
|
||||||
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_UINT16] = "uint16_t",
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LU16] = {"lu16", 2},
|
||||||
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_UINT32] = "uint32_t",
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LU32] = {"lu32", 4},
|
||||||
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_UINT64] = "uint64_t",
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LU64] = {"lu64", 8},
|
||||||
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_INT8] = "int8_t",
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LI8] = {"li8", 1},
|
||||||
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_INT16] = "int16_t",
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LI16] = {"li16", 2},
|
||||||
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_INT32] = "int32_t",
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LI32] = {"li32", 4},
|
||||||
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_INT64] = "int64_t",
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LI64] = {"li64", 8},
|
||||||
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_FLOAT32] = "float",
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BU8] = {"bu8", 1},
|
||||||
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_FLOAT64] = "double",
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BU16] = {"bu16", 2},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BU32] = {"bu32", 4},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BU64] = {"bu64", 8},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI8] = {"bi8", 1},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI16] = {"bi16", 2},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI32] = {"bi32", 4},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI64] = {"bi64", 8},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_F16] = {"f16", 2},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_F32] = {"f32", 4},
|
||||||
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_F64] = {"f64", 8},
|
||||||
};
|
};
|
||||||
|
|
||||||
biner_tree_parse_context_t biner_tree_parse_context_ = {0};
|
biner_tree_parse_context_t biner_tree_parse_context_ = {0};
|
||||||
|
39
tree.h
39
tree.h
@ -8,7 +8,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "./zone.h"
|
#include "./c/zone.h"
|
||||||
|
|
||||||
typedef struct biner_tree_expr_t biner_tree_expr_t;
|
typedef struct biner_tree_expr_t biner_tree_expr_t;
|
||||||
typedef struct biner_tree_struct_member_t biner_tree_struct_member_t;
|
typedef struct biner_tree_struct_member_t biner_tree_struct_member_t;
|
||||||
@ -46,22 +46,37 @@ typedef struct biner_tree_expr_t {
|
|||||||
} biner_tree_expr_t;
|
} biner_tree_expr_t;
|
||||||
|
|
||||||
typedef enum biner_tree_struct_member_type_name_t {
|
typedef enum biner_tree_struct_member_type_name_t {
|
||||||
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_UINT8,
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LU8,
|
||||||
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_UINT16,
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LU16,
|
||||||
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_UINT32,
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LU32,
|
||||||
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_UINT64,
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LU64,
|
||||||
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_INT8,
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LI8,
|
||||||
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_INT16,
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LI16,
|
||||||
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_INT32,
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LI32,
|
||||||
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_INT64,
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_LI64,
|
||||||
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_FLOAT32,
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BU8,
|
||||||
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_FLOAT64,
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BU16,
|
||||||
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BU32,
|
||||||
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BU64,
|
||||||
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI8,
|
||||||
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI16,
|
||||||
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI32,
|
||||||
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI64,
|
||||||
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_F16,
|
||||||
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_F32,
|
||||||
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_F64,
|
||||||
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_USER_DECL,
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_USER_DECL,
|
||||||
|
|
||||||
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_MAX_,
|
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_MAX_,
|
||||||
} biner_tree_struct_member_type_name_t;
|
} biner_tree_struct_member_type_name_t;
|
||||||
|
|
||||||
extern const char* const biner_tree_struct_member_type_name_string_map
|
typedef struct biner_tree_struct_member_type_name_meta_t {
|
||||||
|
const char* name;
|
||||||
|
size_t size;
|
||||||
|
} biner_tree_struct_member_type_name_meta_t;
|
||||||
|
|
||||||
|
extern const biner_tree_struct_member_type_name_meta_t
|
||||||
|
biner_tree_struct_member_type_name_meta_map
|
||||||
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_MAX_];
|
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_MAX_];
|
||||||
|
|
||||||
typedef enum biner_tree_struct_member_type_qualifier_t {
|
typedef enum biner_tree_struct_member_type_qualifier_t {
|
||||||
|
Loading…
Reference in New Issue
Block a user