Supports partial code generation.
This commit is contained in:
parent
601b6fc0d4
commit
64faf74aa6
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
*.swp
|
*.swp
|
||||||
/.build
|
/.build
|
||||||
|
/.rbuild
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
3
TODO.TXT
3
TODO.TXT
@ -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
9
main.c
@ -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;
|
||||||
}
|
}
|
||||||
|
17
transpile.h
17
transpile.h
@ -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;
|
||||||
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user