Supports partial code generation.

This commit is contained in:
falsycat 2021-01-03 00:00:00 +00:00
parent 601b6fc0d4
commit 64faf74aa6
6 changed files with 110 additions and 53 deletions

1
.gitignore vendored
View File

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

View File

@ -33,25 +33,42 @@ target_sources(biner
${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
) )
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}")
if(FUNC_DIVIDE)
add_custom_command( add_custom_command(
OUTPUT "${out}" OUTPUT "${out}.type.h"
COMMAND $<TARGET_FILE:biner> < "${in}" > "${out}" COMMAND $<TARGET_FILE:biner> --only-type < "${in}" > "${out}.type.h"
DEPENDS "${in}" biner DEPENDS "${in}" biner
COMMENT "transpiling ${in} to C" COMMENT "transpiling ${basename} to ${basename}.type.h"
VERBATIM) 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() endforeach()
endfunction() endfunction()

View File

@ -1,4 +1,5 @@
X resolve all TODO in source codes X resolve all TODO in source codes
X remove f16/f32/f64 types 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 release v1.0.1

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

@ -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"
@ -594,42 +595,53 @@ 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");
}
if (func) {
print_func_header_(p, "bool", name, "_validate"); print_func_header_(p, "bool", name, "_validate");
fprintf(p->dst, "uintmax_t v) { "); fprintf(p->dst, "uintmax_t v) { ");
print_enum_member_validation_code_(p, body); print_enum_member_validation_code_(p, body);
fprintf(p->dst, "}\n"); 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");
}
if (type) {
print_typedef_header_(p, "struct", name, CONTEXT_SUFFIX_); print_typedef_header_(p, "struct", name, CONTEXT_SUFFIX_);
print_struct_member_context_struct_(p, body, CONTEXT_SUFFIX_); print_struct_member_context_struct_(p, body, CONTEXT_SUFFIX_);
print_typedef_footer_(p, name, CONTEXT_SUFFIX_); print_typedef_footer_(p, name, CONTEXT_SUFFIX_);
}
if (func) {
print_func_header_(p, "biner_result_t", name, "_pack"); print_func_header_(p, "biner_result_t", name, "_pack");
print_fixed_decl_name_(p, name); print_fixed_decl_name_(p, name);
fprintf(p->dst, CONTEXT_SUFFIX_"* ctx, "); fprintf(p->dst, CONTEXT_SUFFIX_"* ctx, ");
@ -640,7 +652,8 @@ static void print_decls_(
print_struct_member_iteration_code_( print_struct_member_iteration_code_(
p, body, &print_struct_member_pack_code_each_); p, body, &print_struct_member_pack_code_each_);
fprintf(p->dst, "}\n"); fprintf(p->dst, "}\n");
}
if (func) {
print_func_header_(p, "biner_result_t", name, "_unpack"); print_func_header_(p, "biner_result_t", name, "_unpack");
print_fixed_decl_name_(p, name); print_fixed_decl_name_(p, name);
fprintf(p->dst, CONTEXT_SUFFIX_"* ctx, "); fprintf(p->dst, CONTEXT_SUFFIX_"* ctx, ");
@ -650,6 +663,7 @@ static void print_decls_(
print_struct_member_iteration_code_( print_struct_member_iteration_code_(
p, body, &print_struct_member_unpack_code_each_); p, body, &print_struct_member_unpack_code_each_);
fprintf(p->dst, "}\n"); fprintf(p->dst, "}\n");
}
} break; } break;
} }
} }