From 64faf74aa62b96381bfa3d39e6f56706574c1100 Mon Sep 17 00:00:00 2001 From: falsycat Date: Sun, 3 Jan 2021 00:00:00 +0000 Subject: [PATCH] Supports partial code generation. --- .gitignore | 1 + CMakeLists.txt | 35 +++++++++++++----- TODO.TXT | 3 +- main.c | 9 ++++- transpile.h | 17 +++++++++ transpile_c.c | 98 ++++++++++++++++++++++++++++---------------------- 6 files changed, 110 insertions(+), 53 deletions(-) diff --git a/.gitignore b/.gitignore index 056d00e..f0c36da 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.swp /.build +/.rbuild diff --git a/CMakeLists.txt b/CMakeLists.txt index 5300119..09fa413 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,25 +33,42 @@ target_sources(biner ${FLEX_biner-scanner_OUTPUTS} PUBLIC c/pack.h + c/result.h c/unpack.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") - add_custom_command( - OUTPUT "${out}" - COMMAND $ < "${in}" > "${out}" - DEPENDS "${in}" biner - COMMENT "transpiling ${in} to C" - VERBATIM) - target_sources(${target} PRIVATE "${out}") + set(out "${FUNC_OUTPUT}/${basename}") + if(FUNC_DIVIDE) + add_custom_command( + OUTPUT "${out}.type.h" + COMMAND $ --only-type < "${in}" > "${out}.type.h" + DEPENDS "${in}" biner + COMMENT "transpiling ${basename} to ${basename}.type.h" + VERBATIM) + add_custom_command( + OUTPUT "${out}.func.h" + COMMAND $ --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 $ < "${in}" > "${out}.h" + DEPENDS "${in}" biner + COMMENT "transpiling ${basename} to ${basename}.h" + VERBATIM) + target_sources(${target} PRIVATE "${out}.h" "${out}.h") + endif() endforeach() endfunction() diff --git a/TODO.TXT b/TODO.TXT index c174187..b030817 100644 --- a/TODO.TXT +++ b/TODO.TXT @@ -1,4 +1,5 @@ X resolve all TODO in source codes X remove f16/f32/f64 types - partial code generation for C (divide decls and functions) +X partial code generation for C (divide decls and functions) + update README release v1.0.1 diff --git a/main.c b/main.c index 653123c..542016f 100644 --- a/main.c +++ b/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; } diff --git a/transpile.h b/transpile.h index 88ba0cc..ce393c9 100644 --- a/transpile.h +++ b/transpile.h @@ -1,15 +1,32 @@ #pragma once +#include #include +#include #include #include +#include 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; +} diff --git a/transpile_c.c b/transpile_c.c index 01c2e2a..95da95d 100644 --- a/transpile_c.c +++ b/transpile_c.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "./tree.h" @@ -594,62 +595,75 @@ 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_); - - fprintf(p->dst, "#define %s (", name); - print_expr_(p, body); - fprintf(p->dst, ")\n"); + 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_); - - 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"); + 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_); - - 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, 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); - fprintf(p->dst, CONTEXT_SUFFIX_"* ctx, "); - fprintf(p->dst, "const "); - print_fixed_decl_name_(p, name); - fprintf(p->dst, "_t* s, "); - fprintf(p->dst, "uint8_t* c) { "); - print_struct_member_iteration_code_( - p, body, &print_struct_member_pack_code_each_); - fprintf(p->dst, "}\n"); - - print_func_header_(p, "biner_result_t", name, "_unpack"); - print_fixed_decl_name_(p, name); - fprintf(p->dst, CONTEXT_SUFFIX_"* ctx, "); - print_fixed_decl_name_(p, name); - fprintf(p->dst, "_t* s, "); - fprintf(p->dst, "uint8_t c) { "); - print_struct_member_iteration_code_( - p, body, &print_struct_member_unpack_code_each_); - fprintf(p->dst, "}\n"); + 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, "); + fprintf(p->dst, "const "); + print_fixed_decl_name_(p, name); + fprintf(p->dst, "_t* s, "); + fprintf(p->dst, "uint8_t* c) { "); + 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, "); + print_fixed_decl_name_(p, name); + fprintf(p->dst, "_t* s, "); + fprintf(p->dst, "uint8_t c) { "); + print_struct_member_iteration_code_( + p, body, &print_struct_member_unpack_code_each_); + fprintf(p->dst, "}\n"); + } } break; } }