Compare commits

..

8 Commits
v1.0.0 ... main

12 changed files with 161 additions and 90 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
*.swp *.swp
/.build /.build
/.rbuild

View File

@ -24,32 +24,51 @@ add_executable(biner)
target_sources(biner target_sources(biner
PRIVATE PRIVATE
main.c main.c
transpile.h
transpile_c.c transpile_c.c
tree.h
tree.c tree.c
zone.h
${BISON_biner-parser_OUTPUTS} ${BISON_biner-parser_OUTPUTS}
${FLEX_biner-scanner_OUTPUTS} ${FLEX_biner-scanner_OUTPUTS}
PUBLIC PUBLIC
c/pack.h c/pack.h
c/result.h
c/unpack.h c/unpack.h
c/zone.h
) )
target_include_directories(biner PRIVATE . ${CMAKE_CURRENT_BINARY_DIR}) target_include_directories(biner PRIVATE . ${CMAKE_CURRENT_BINARY_DIR})
function(target_biner_sources target) function(target_biner_sources target)
cmake_parse_arguments("FUNC" "" "OUTPUT" "SOURCES" ${ARGN}) cmake_parse_arguments("FUNC" "DIVIDE" "OUTPUT" "SOURCES" ${ARGN})
file(MAKE_DIRECTORY "${FUNC_OUTPUT}") file(MAKE_DIRECTORY "${FUNC_OUTPUT}")
foreach(path ${FUNC_SOURCES}) foreach(path ${FUNC_SOURCES})
get_filename_component(basename "${path}" NAME) get_filename_component(basename "${path}" NAME)
set(in "${CMAKE_CURRENT_SOURCE_DIR}/${path}") set(in "${CMAKE_CURRENT_SOURCE_DIR}/${path}")
set(out "${FUNC_OUTPUT}/${basename}.h") set(out "${FUNC_OUTPUT}/${basename}")
add_custom_command( if(FUNC_DIVIDE)
OUTPUT "${out}" add_custom_command(
COMMAND $<TARGET_FILE:biner> < "${in}" > "${out}" OUTPUT "${out}.type.h"
DEPENDS "${in}" biner COMMAND $<TARGET_FILE:biner> --only-type < "${in}" > "${out}.type.h"
COMMENT "transpiling ${in} to C" DEPENDS "${in}" biner
VERBATIM) COMMENT "transpiling ${basename} to ${basename}.type.h"
target_sources(${target} PRIVATE "${out}") VERBATIM)
add_custom_command(
OUTPUT "${out}.func.h"
COMMAND $<TARGET_FILE:biner> --only-func < "${in}" > "${out}.func.h"
DEPENDS "${in}" biner
COMMENT "transpiling ${basename} to ${basename}.func.h"
VERBATIM)
target_sources(${target} PRIVATE "${out}.type.h" "${out}.func.h")
else()
add_custom_command(
OUTPUT "${out}.h"
COMMAND $<TARGET_FILE:biner> < "${in}" > "${out}.h"
DEPENDS "${in}" biner
COMMENT "transpiling ${basename} to ${basename}.h"
VERBATIM)
target_sources(${target} PRIVATE "${out}.h" "${out}.h")
endif()
endforeach() endforeach()
endfunction() endfunction()

View File

@ -36,7 +36,7 @@ You can get an example from `test` directory.
## license ## license
What The Fuck You Want To Public License Do What The Fuck You Want To Public License
## author ## author

42
biner.l
View File

@ -4,14 +4,15 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <inttypes.h> #include <inttypes.h>
#include <stdbool.h>
#include "./tree.h" #include "./tree.h"
#include "./c/zone.h" #include "./zone.h"
#include "generated/biner.y.h" #include "generated/biner.y.h"
static inline biner_zone_ptr(char) strnew_(void); static inline biner_zone_ptr(char) strnew_(void);
static inline intmax_t parse_int_(int base); static inline bool parse_int_(intmax_t* v, int base);
static inline void count_(void); static inline void count_(void);
%} %}
@ -19,10 +20,18 @@ D [0-9]
I [A-Za-z_] I [A-Za-z_]
H [0-9A-Fa-f] H [0-9A-Fa-f]
%x IN_COMMENT
%% %%
"//".* count_(); [ \t\r\n]+ count_();
[/][*][^*]*[*]+([^*/][^*]*[*]+)*[/] count_(); /* TODO: detect unterminated comment */ "//".* count_();
<INITIAL>"/*" { count_(); BEGIN(IN_COMMENT); }
<IN_COMMENT>"*/" { count_(); BEGIN(INITIAL); }
<IN_COMMENT>[^\*\n]+ count_();
<IN_COMMENT>"*" count_();
<IN_COMMENT>"\n" count_();
"==" { count_(); return EQUAL; } "==" { count_(); return EQUAL; }
"!=" { count_(); return NEQUAL; } "!=" { count_(); return NEQUAL; }
@ -40,27 +49,24 @@ H [0-9A-Fa-f]
{I}({I}|{D})* { yylval.ptr = strnew_(); count_(); return IDENT; } {I}({I}|{D})* { yylval.ptr = strnew_(); count_(); return IDENT; }
{D}+ { yylval.i = parse_int_(10); count_(); return INTEGER; } {D}+ { return parse_int_(&yylval.i, 10)? INTEGER: OVERFLOWN_INTEGER; }
0[xX]{H}+ { yylval.i = parse_int_(16); count_(); return INTEGER; } 0[xX]{H}+ { return parse_int_(&yylval.i, 16)? INTEGER: OVERFLOWN_INTEGER; }
[\+\-\*\/\!\=\<\>\.\(\)[\]\{\}\;\,\&\|\~\^] { count_(); return yytext[0]; } . { count_(); return yytext[0]; }
(.|\n) count_();
%% %%
static inline uintptr_t strnew_(void) { static inline uintptr_t strnew_(void) {
return biner_zone_strnew(&biner_tree_parse_context_.zone, yytext); return biner_zone_strnew(&biner_tree_parse_context_.zone, yytext);
} }
static inline intmax_t parse_int_(int base) { static inline bool parse_int_(intmax_t* v, int base) {
char* end = NULL; assert(v != NULL);
const intmax_t v = strtoimax(yytext, &end, base);
/* TODO: replace asserts with throwing error */ char* end = NULL;
assert((v != INTMAX_MIN && v != INTMAX_MAX) || errno != ERANGE); *v = strtoimax(yytext, &end, base);
assert(INT64_MIN <= v && v <= INT64_MAX); return
assert(end != NULL && *end == 0); ((*v != INTMAX_MIN && *v != INTMAX_MAX) || errno != ERANGE) &&
(INT64_MIN <= *v && *v <= INT64_MAX) &&
return v; (end != NULL && *end == 0);
} }
static inline void count_(void) { static inline void count_(void) {
const char* s = yytext; const char* s = yytext;

22
biner.y
View File

@ -8,7 +8,7 @@
#include <string.h> #include <string.h>
#include "./tree.h" #include "./tree.h"
#include "./c/zone.h" #include "./zone.h"
#define ctx (biner_tree_parse_context_) #define ctx (biner_tree_parse_context_)
@ -90,10 +90,12 @@ resolve_constant_(
uintptr_t ptr; uintptr_t ptr;
} }
%token OVERFLOWN_INTEGER
%token EQUAL NEQUAL LESS_EQUAL GREATER_EQUAL AND OR BIT_LSHIFT BIT_RSHIFT %token EQUAL NEQUAL LESS_EQUAL GREATER_EQUAL AND OR BIT_LSHIFT BIT_RSHIFT
%token CONST ENUM STRUCT UNION %token CONST ENUM STRUCT UNION
%token <ptr> IDENT %token <ptr> IDENT
%token <i> INTEGER; %token <i> INTEGER
%type <ptr> decl_list decl %type <ptr> decl_list decl
%type <ptr> enum_member_list enum_member %type <ptr> enum_member_list enum_member
@ -101,8 +103,8 @@ resolve_constant_(
%type <ptr> struct_member_type array_struct_member_type unqualified_struct_member_type %type <ptr> struct_member_type array_struct_member_type unqualified_struct_member_type
%type <ptr> expr or_expr and_expr bit_or_expr bit_xor_expr %type <ptr> expr or_expr and_expr bit_or_expr bit_xor_expr
%type <ptr> bit_and_expr equality_expr relational_expr add_expr %type <ptr> bit_and_expr equality_expr relational_expr shift_expr
%type <ptr> mul_expr unary_expr operand %type <ptr> add_expr mul_expr unary_expr operand
%start decl_list %start decl_list
@ -312,7 +314,7 @@ equality_expr
; ;
relational_expr relational_expr
: add_expr : shift_expr
| relational_expr '>' add_expr { | relational_expr '>' add_expr {
$$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_GREATER, $3); $$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_GREATER, $3);
} }
@ -327,6 +329,16 @@ relational_expr
} }
; ;
shift_expr
: add_expr
| shift_expr BIT_LSHIFT add_expr {
$$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_BIT_LSHIFT, $3);
}
| shift_expr BIT_RSHIFT add_expr {
$$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_BIT_RSHIFT, $3);
}
;
add_expr add_expr
: mul_expr : mul_expr
| add_expr '+' mul_expr { | add_expr '+' mul_expr {

9
main.c
View File

@ -5,13 +5,20 @@
#include "./transpile.h" #include "./transpile.h"
#include "./tree.h" #include "./tree.h"
int main(void) { int main(int argc, char** argv) {
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;
if (argc == 0) {
fprintf(stderr, "assertion failure: argc > 1");
return EXIT_FAILURE;
}
biner_transpile_c(&(biner_transpile_param_t) { biner_transpile_c(&(biner_transpile_param_t) {
.zone = zone, .zone = zone,
.dst = stdout, .dst = stdout,
.argc = argc-1,
.argv = argv+1,
}); });
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -29,8 +29,8 @@ struct teacher_t {
}; };
struct student_t { struct student_t {
lu8[10] scores; lu8[(1 << 4) - 6] scores;
lu8 absents; lu8 absents;
}; };
struct user_t { struct user_t {

View File

@ -1,15 +1,32 @@
#pragma once #pragma once
#include <assert.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
typedef struct biner_transpile_param_t { typedef struct biner_transpile_param_t {
const uint8_t* zone; const uint8_t* zone;
FILE* dst; FILE* dst;
size_t argc;
char** argv;
} biner_transpile_param_t; } biner_transpile_param_t;
bool bool
biner_transpile_c( biner_transpile_c(
const biner_transpile_param_t* p const biner_transpile_param_t* p
); );
static inline bool biner_transpile_is_option_enabled(
const biner_transpile_param_t* p, const char* name) {
assert(p != NULL);
assert(name != NULL);
for (size_t i = 0; i < p->argc; ++i) {
if (strcmp(p->argv[i], name) == 0) return true;
}
return false;
}

View File

@ -6,6 +6,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include "./tree.h" #include "./tree.h"
@ -34,9 +35,6 @@ static const struct_member_type_name_meta_t struct_member_type_name_meta_map_
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI16] = {"b16", "int16_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_BI32] = {"b32", "int32_t"},
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI64] = {"b64", "int64_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"},
}; };
static const char* const expr_operator_string_map_ static const char* const expr_operator_string_map_
@ -58,6 +56,8 @@ static const char* const expr_operator_string_map_
[BINER_TREE_EXPR_TYPE_OPERATOR_BIT_OR] = "|", [BINER_TREE_EXPR_TYPE_OPERATOR_BIT_OR] = "|",
[BINER_TREE_EXPR_TYPE_OPERATOR_BIT_NOT] = "~", [BINER_TREE_EXPR_TYPE_OPERATOR_BIT_NOT] = "~",
[BINER_TREE_EXPR_TYPE_OPERATOR_BIT_XOR] = "^", [BINER_TREE_EXPR_TYPE_OPERATOR_BIT_XOR] = "^",
[BINER_TREE_EXPR_TYPE_OPERATOR_BIT_LSHIFT] = "<<",
[BINER_TREE_EXPR_TYPE_OPERATOR_BIT_RSHIFT] = ">>",
}; };
typedef struct struct_member_info_t { typedef struct struct_member_info_t {
@ -597,62 +597,75 @@ static void print_decls_(
print_decls_(p, (const biner_tree_decl_t*) (p->zone+d->prev)); print_decls_(p, (const biner_tree_decl_t*) (p->zone+d->prev));
} }
const bool only_type = biner_transpile_is_option_enabled(p, "--only-type");
const bool only_func = biner_transpile_is_option_enabled(p, "--only-func");
const bool type = only_type || (!only_type && !only_func);
const bool func = only_func || (!only_type && !only_func);
const char* name = (const char*) (p->zone+d->name); const char* name = (const char*) (p->zone+d->name);
switch (d->type) { switch (d->type) {
case BINER_TREE_DECL_TYPE_CONST: { case BINER_TREE_DECL_TYPE_CONST: {
const biner_tree_expr_t* body = const biner_tree_expr_t* body =
(const biner_tree_expr_t*) (p->zone+d->const_); (const biner_tree_expr_t*) (p->zone+d->const_);
if (type) {
fprintf(p->dst, "#define %s (", name); fprintf(p->dst, "#define %s (", name);
print_expr_(p, body); print_expr_(p, body);
fprintf(p->dst, ")\n"); fprintf(p->dst, ")\n");
}
} break; } break;
case BINER_TREE_DECL_TYPE_ENUM: { case BINER_TREE_DECL_TYPE_ENUM: {
const biner_tree_enum_member_t* body = const biner_tree_enum_member_t* body =
(const biner_tree_enum_member_t*) (p->zone+d->enum_); (const biner_tree_enum_member_t*) (p->zone+d->enum_);
if (type) {
print_typedef_header_(p, "enum", name, "_t"); print_typedef_header_(p, "enum", name, "_t");
print_enum_member_decls_(p, body); print_enum_member_decls_(p, body);
print_typedef_footer_(p, name, "_t"); print_typedef_footer_(p, name, "_t");
}
print_func_header_(p, "bool", name, "_validate"); if (func) {
fprintf(p->dst, "uintmax_t v) { "); print_func_header_(p, "bool", name, "_validate");
print_enum_member_validation_code_(p, body); fprintf(p->dst, "uintmax_t v) { ");
fprintf(p->dst, "}\n"); print_enum_member_validation_code_(p, body);
fprintf(p->dst, "}\n");
}
} break; } break;
case BINER_TREE_DECL_TYPE_STRUCT: { case BINER_TREE_DECL_TYPE_STRUCT: {
const biner_tree_struct_member_t* body = const biner_tree_struct_member_t* body =
(const biner_tree_struct_member_t*) (p->zone+d->struct_); (const biner_tree_struct_member_t*) (p->zone+d->struct_);
if (type) {
print_typedef_header_(p, "struct", name, "_t"); print_typedef_header_(p, "struct", name, "_t");
struct_member_each_(p, body, print_struct_member_decl_, SIZE_MAX); struct_member_each_(p, body, print_struct_member_decl_, SIZE_MAX);
print_typedef_footer_(p, name, "_t"); print_typedef_footer_(p, name, "_t");
}
print_typedef_header_(p, "struct", name, CONTEXT_SUFFIX_); if (type) {
print_struct_member_context_struct_(p, body, CONTEXT_SUFFIX_); print_typedef_header_(p, "struct", name, CONTEXT_SUFFIX_);
print_typedef_footer_(p, name, CONTEXT_SUFFIX_); print_struct_member_context_struct_(p, body, CONTEXT_SUFFIX_);
print_typedef_footer_(p, name, CONTEXT_SUFFIX_);
print_func_header_(p, "biner_result_t", name, "_pack"); }
print_fixed_decl_name_(p, name); if (func) {
fprintf(p->dst, CONTEXT_SUFFIX_"* ctx, "); print_func_header_(p, "biner_result_t", name, "_pack");
fprintf(p->dst, "const "); print_fixed_decl_name_(p, name);
print_fixed_decl_name_(p, name); fprintf(p->dst, CONTEXT_SUFFIX_"* ctx, ");
fprintf(p->dst, "_t* s, "); fprintf(p->dst, "const ");
fprintf(p->dst, "uint8_t* c) { "); print_fixed_decl_name_(p, name);
print_struct_member_iteration_code_( fprintf(p->dst, "_t* s, ");
p, body, &print_struct_member_pack_code_each_); fprintf(p->dst, "uint8_t* c) { ");
fprintf(p->dst, "}\n"); print_struct_member_iteration_code_(
p, body, &print_struct_member_pack_code_each_);
print_func_header_(p, "biner_result_t", name, "_unpack"); fprintf(p->dst, "}\n");
print_fixed_decl_name_(p, name); }
fprintf(p->dst, CONTEXT_SUFFIX_"* ctx, "); if (func) {
print_fixed_decl_name_(p, name); print_func_header_(p, "biner_result_t", name, "_unpack");
fprintf(p->dst, "_t* s, "); print_fixed_decl_name_(p, name);
fprintf(p->dst, "uint8_t c) { "); fprintf(p->dst, CONTEXT_SUFFIX_"* ctx, ");
print_struct_member_iteration_code_( print_fixed_decl_name_(p, name);
p, body, &print_struct_member_unpack_code_each_); fprintf(p->dst, "_t* s, ");
fprintf(p->dst, "}\n"); fprintf(p->dst, "uint8_t c) { ");
print_struct_member_iteration_code_(
p, body, &print_struct_member_unpack_code_each_);
fprintf(p->dst, "}\n");
}
} break; } break;
} }
} }

5
tree.c
View File

@ -8,7 +8,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "./c/zone.h" #include "./zone.h"
#include "generated/biner.y.h" #include "generated/biner.y.h"
@ -31,9 +31,6 @@ biner_tree_struct_member_type_name_meta_map
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI16] = {"bi16", 2}, [BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI16] = {"bi16", 2},
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI32] = {"bi32", 4}, [BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI32] = {"bi32", 4},
[BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI64] = {"bi64", 8}, [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};

7
tree.h
View File

@ -8,7 +8,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "./c/zone.h" #include "./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;
@ -36,6 +36,8 @@ typedef enum biner_tree_expr_type_t {
BINER_TREE_EXPR_TYPE_OPERATOR_BIT_OR, BINER_TREE_EXPR_TYPE_OPERATOR_BIT_OR,
BINER_TREE_EXPR_TYPE_OPERATOR_BIT_NOT, BINER_TREE_EXPR_TYPE_OPERATOR_BIT_NOT,
BINER_TREE_EXPR_TYPE_OPERATOR_BIT_XOR, BINER_TREE_EXPR_TYPE_OPERATOR_BIT_XOR,
BINER_TREE_EXPR_TYPE_OPERATOR_BIT_LSHIFT,
BINER_TREE_EXPR_TYPE_OPERATOR_BIT_RSHIFT,
BINER_TREE_EXPR_TYPE_OPERATOR_MAX_, BINER_TREE_EXPR_TYPE_OPERATOR_MAX_,
} biner_tree_expr_type_t; } biner_tree_expr_type_t;
@ -70,9 +72,6 @@ typedef enum biner_tree_struct_member_type_name_t {
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI16, BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI16,
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI32, BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI32,
BINER_TREE_STRUCT_MEMBER_TYPE_NAME_BI64, 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_,

View File