Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
65c819cae6 | |||
d0ff990914 | |||
ad3fbc58d9 | |||
64faf74aa6 | |||
601b6fc0d4 | |||
c5cf9aa530 | |||
967dc2cf3f | |||
fb43a77ec6 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
*.swp
|
||||
/.build
|
||||
/.rbuild
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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
40
biner.l
@ -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
22
biner.y
@ -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
9
main.c
@ -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;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ struct teacher_t {
|
||||
};
|
||||
|
||||
struct student_t {
|
||||
lu8[10] scores;
|
||||
lu8[(1 << 4) - 6] scores;
|
||||
lu8 absents;
|
||||
};
|
||||
|
||||
|
17
transpile.h
17
transpile.h
@ -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;
|
||||
}
|
||||
|
@ -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
5
tree.c
@ -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
7
tree.h
@ -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_,
|
||||
|
Loading…
x
Reference in New Issue
Block a user