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

View File

@ -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 $<TARGET_FILE:biner> < "${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 $<TARGET_FILE:biner> --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 $<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

@ -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

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

@ -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"
@ -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;
}
}