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
/.build
/.rbuild

View File

@ -24,32 +24,51 @@ add_executable(biner)
target_sources(biner
PRIVATE
main.c
transpile.h
transpile_c.c
tree.h
tree.c
zone.h
${BISON_biner-parser_OUTPUTS}
${FLEX_biner-scanner_OUTPUTS}
PUBLIC
c/pack.h
c/result.h
c/unpack.h
c/zone.h
)
target_include_directories(biner PRIVATE . ${CMAKE_CURRENT_BINARY_DIR})
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}")
foreach(path ${FUNC_SOURCES})
get_filename_component(basename "${path}" NAME)
set(in "${CMAKE_CURRENT_SOURCE_DIR}/${path}")
set(out "${FUNC_OUTPUT}/${basename}.h")
set(out "${FUNC_OUTPUT}/${basename}")
if(FUNC_DIVIDE)
add_custom_command(
OUTPUT "${out}"
COMMAND $<TARGET_FILE:biner> < "${in}" > "${out}"
OUTPUT "${out}.type.h"
COMMAND $<TARGET_FILE:biner> --only-type < "${in}" > "${out}.type.h"
DEPENDS "${in}" biner
COMMENT "transpiling ${in} to C"
COMMENT "transpiling ${basename} to ${basename}.type.h"
VERBATIM)
target_sources(${target} PRIVATE "${out}")
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()
endfunction()

View File

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

40
biner.l
View File

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

22
biner.y
View File

@ -8,7 +8,7 @@
#include <string.h>
#include "./tree.h"
#include "./c/zone.h"
#include "./zone.h"
#define ctx (biner_tree_parse_context_)
@ -90,10 +90,12 @@ resolve_constant_(
uintptr_t ptr;
}
%token OVERFLOWN_INTEGER
%token EQUAL NEQUAL LESS_EQUAL GREATER_EQUAL AND OR BIT_LSHIFT BIT_RSHIFT
%token CONST ENUM STRUCT UNION
%token <ptr> IDENT
%token <i> INTEGER;
%token <i> INTEGER
%type <ptr> decl_list decl
%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> expr or_expr and_expr bit_or_expr bit_xor_expr
%type <ptr> bit_and_expr equality_expr relational_expr add_expr
%type <ptr> mul_expr unary_expr operand
%type <ptr> bit_and_expr equality_expr relational_expr shift_expr
%type <ptr> add_expr mul_expr unary_expr operand
%start decl_list
@ -312,7 +314,7 @@ equality_expr
;
relational_expr
: add_expr
: shift_expr
| relational_expr '>' add_expr {
$$ = 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
: mul_expr
| add_expr '+' mul_expr {

9
main.c
View File

@ -5,13 +5,20 @@
#include "./transpile.h"
#include "./tree.h"
int main(void) {
int main(int argc, char** argv) {
const uint8_t* zone = biner_tree_parse(stdin);
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) {
.zone = zone,
.dst = stdout,
.argc = argc-1,
.argv = argv+1,
});
return EXIT_SUCCESS;
}

View File

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

View File

@ -1,15 +1,32 @@
#pragma once
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
typedef struct biner_transpile_param_t {
const uint8_t* zone;
FILE* dst;
size_t argc;
char** argv;
} biner_transpile_param_t;
bool
biner_transpile_c(
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 <stdint.h>
#include <stdio.h>
#include <string.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_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"},
};
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_NOT] = "~",
[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 {
@ -597,42 +597,53 @@ static void print_decls_(
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);
switch (d->type) {
case BINER_TREE_DECL_TYPE_CONST: {
const biner_tree_expr_t* body =
(const biner_tree_expr_t*) (p->zone+d->const_);
if (type) {
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_);
if (type) {
print_typedef_header_(p, "enum", name, "_t");
print_enum_member_decls_(p, body);
print_typedef_footer_(p, name, "_t");
}
if (func) {
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_);
if (type) {
print_typedef_header_(p, "struct", name, "_t");
struct_member_each_(p, body, print_struct_member_decl_, SIZE_MAX);
print_typedef_footer_(p, name, "_t");
}
if (type) {
print_typedef_header_(p, "struct", name, CONTEXT_SUFFIX_);
print_struct_member_context_struct_(p, body, CONTEXT_SUFFIX_);
print_typedef_footer_(p, name, CONTEXT_SUFFIX_);
}
if (func) {
print_func_header_(p, "biner_result_t", name, "_pack");
print_fixed_decl_name_(p, name);
fprintf(p->dst, CONTEXT_SUFFIX_"* ctx, ");
@ -643,7 +654,8 @@ static void print_decls_(
print_struct_member_iteration_code_(
p, body, &print_struct_member_pack_code_each_);
fprintf(p->dst, "}\n");
}
if (func) {
print_func_header_(p, "biner_result_t", name, "_unpack");
print_fixed_decl_name_(p, name);
fprintf(p->dst, CONTEXT_SUFFIX_"* ctx, ");
@ -653,6 +665,7 @@ static void print_decls_(
print_struct_member_iteration_code_(
p, body, &print_struct_member_unpack_code_each_);
fprintf(p->dst, "}\n");
}
} break;
}
}

5
tree.c
View File

@ -8,7 +8,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "./c/zone.h"
#include "./zone.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_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};

7
tree.h
View File

@ -8,7 +8,7 @@
#include <stdio.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_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_NOT,
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_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_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_MAX_,

View File