From 8780906c1e2ee7cac2bf0e96f1eef96eb8acbc4a Mon Sep 17 00:00:00 2001 From: Ludovic 'Archivist' Lagouardette Date: Tue, 1 Dec 2020 15:26:13 +0100 Subject: [PATCH] some work on source file generation --- generator/src/generator.c | 196 +++++++++++++++++++++++++++++++------- generator/src/main.c | 2 + generator/src/tstring.c | 6 +- 3 files changed, 167 insertions(+), 37 deletions(-) diff --git a/generator/src/generator.c b/generator/src/generator.c index 4baf59b..57e4d2e 100644 --- a/generator/src/generator.c +++ b/generator/src/generator.c @@ -5,6 +5,7 @@ void generator( tstring* header_filename, + tstring* source_filename, tstring* prefix, tstring* bucket_count, tstring* K_size, tstring* K_comp_pred, tstring* K_hash_func, @@ -40,7 +41,10 @@ void generator( "size_t operator()(",key_type," key) {\n" "return ", K_hash_func, "(key);\n" "}\n" - "}\n" + "};\n" + ); + tstring* hash_type = tstring_n_compose("tc", + prefix,"_hashtype" ); tstring* hashmap_ptr_type = tstring_n_compose("tc", prefix,"_hashmap_ptr" @@ -48,24 +52,32 @@ void generator( tstring* hashmap_decl = tstring_n_compose("ctc", "typedef void* ",hashmap_ptr_type,";\n" ); + tstring* cpp_hashmap_type = tstring_n_compose("ctctctctc", + "mct20::lfhmap<",key_type,",",value_type,",",bucket_count,",",hash_type,">" + ); + tstring* cpp_hashmap_ptr_type = tstring_n_compose("tc", + cpp_hashmap_type,"*" + ); + tstring* create_hashmap_decl = tstring_n_compose("tctc", hashmap_ptr_type," ",prefix,"_hm_create();\n" ); tstring* destroy_hashmap_decl = tstring_n_compose("ctctc", "void ", prefix, "_hm_destroy(",hashmap_ptr_type,");\n" ); - tstring* hashmap_push_decl = tstring_n_compose("ctctctc", - "void ", prefix, "_hm_push(",key_type,"* k, ",value_type,"* v);\n" + tstring* hashmap_push_decl = tstring_n_compose("ctctctctc", + "void ", prefix, "_hm_push(",hashmap_ptr_type," ptr, ",key_type,"* k, ",value_type,"* v);\n" ); - tstring* hashmap_get_decl = tstring_n_compose("tctctc", - accessor_type, " ", prefix, "_hm_get(",key_type,"* k);\n" + tstring* hashmap_get_decl = tstring_n_compose("tctctctc", + accessor_type, " ", prefix, "_hm_get(",hashmap_ptr_type," ptr, ",key_type,"* k);\n" ); - tstring* hashmap_endget_decl = tstring_n_compose("ctctc", + tstring* hashmap_endget_decl = tstring_n_compose("ctctctc", "void ", prefix, "_hm_endget(",accessor_type," acc);\n" ); - tstring* hashmap_remove_decl = tstring_n_compose("ctctc", - "void ", prefix, "_hm_remove(",key_type,"* k);\n" + tstring* hashmap_remove_decl = tstring_n_compose("ctctctc", + "void ", prefix, "_hm_remove(",hashmap_ptr_type," ptr, ",key_type,"* k);\n" ); + tstring* top_guard = tstring_n_compose("ctctc", "#ifndef GUARD_", prefix, "\n#define GUARD_", prefix,"\n\n" @@ -73,32 +85,146 @@ void generator( tstring* bottom_guard = tstring_n_compose("ctc", "\n#endif // GUARD_", prefix, "\n" ); - FILE* header; - if( - !(header = fopen(header_filename->data, "w")) - ) { - char* m = header_filename->data; - fprintf(stderr, "Couldn't open header file: %s\n", header_filename->data); - exit(EXIT_FAILURE); + tstring* extc_top_guard = cstring_to_tstring( + "#ifdef __cplusplus\n" + "extern \"C\" {\n" + "#endif\n" + ); + tstring* extc_bottom_guard = cstring_to_tstring( + "#ifdef __cplusplus\n" + "}\n" + "#endif\n" + ); + tstring* cpp_header_include = cstring_to_tstring( + "#include \"lfhmap.hpp\"\n" + ); + tstring* key_equality_predicate_handler = tstring_n_compose("ctctctctc", + "bool operator==(",key_type,"& lhs,",key_type,"& rhs) {\n" + " return K_comp_pred((void*)&lhs,(void*)&rhs);\n" + "}\n" + "bool operator!=(",key_type,"& lhs,",key_type,"& rhs) {\n" + " return !K_comp_pred((void*)&lhs,(void*)&rhs);\n" + "}\n" + ); + tstring* to_cpp_hashmap_cast = tstring_n_compose("ctc", + "(", cpp_hashmap_ptr_type, ")" + ); + tstring* from_cpp_hashmap_cast = tstring_n_compose("ctc", + "(", hashmap_ptr_type, ")" + ); + + tstring* create_hashmap_impl = tstring_n_compose("tctctctc", + hashmap_ptr_type," ",prefix,"_hm_create(){\n" + " return ",from_cpp_hashmap_cast,"new ",cpp_hashmap_type,"();\n" + "}\n" + ); + tstring* destroy_hashmap_impl = tstring_n_compose("ctctctc", + "void ", prefix, "_hm_destroy(",hashmap_ptr_type," value){\n" + " delete ",to_cpp_hashmap_cast,"value;\n" + "}\n" + ); + + tstring* hashmap_push_impl = tstring_n_compose("ctctctctctc", + "void ", prefix, "_hm_push(",hashmap_ptr_type," ptr, ",key_type,"* k, ",value_type,"* v){\n" + " (",to_cpp_hashmap_cast,"ptr)->set(*k, *v);\n" + "}\n" + ); + tstring* hashmap_get_impl = tstring_n_compose("tctctctctctctc", + accessor_type, " ", prefix, "_hm_get(",hashmap_ptr_type," ptr, ",key_type,"* k){\n", + accessor_type, " acc;\n" + " auto obtained = (",to_cpp_hashmap_cast,"ptr)->get(*k);\n" + " if(obtained) {\n" + " acc.value = (void*)new accessor<",value_type,">(obtained.value());\n" + " } else {\n" + " acc.value = nullptr;\n" + " }\n" + "}\n" + ); + tstring* hashmap_endget_impl = tstring_n_compose("ctctctc", + "void ", prefix, "_hm_endget(",accessor_type," acc) {\n" + " delete (accessor<",value_type,">*)acc.value;\n" + "}\n" + ); + tstring* hashmap_remove_impl = tstring_n_compose("ctctctctc", + "void ", prefix, "_hm_remove(",hashmap_ptr_type," ptr, ",key_type,"* k) {\n" + " (",to_cpp_hashmap_cast,"ptr)->remove(*k);\n" + "}\n" + ); + + { + FILE* header; + if( + !(header = fopen(header_filename->data, "w")) + ) { + char* m = header_filename->data; + fprintf(stderr, "Couldn't open header file: %s\n", header_filename->data); + exit(EXIT_FAILURE); + } + if( + tstring_n_write( + header,14, + top_guard, + extc_top_guard, + key_type_decl, + value_type_decl, + accessor_type_decl, + hashmap_decl, + create_hashmap_decl, + destroy_hashmap_decl, + hashmap_get_decl, + hashmap_endget_decl, + hashmap_push_decl, + hashmap_remove_decl, + extc_bottom_guard, + bottom_guard + ) != 0 + ) { + fprintf(stderr, "Couldn't generate header file: error writing to file: %s\n", header_filename->data); + exit(EXIT_FAILURE); + } + fclose(header); } - if( - tstring_n_write( - header,12, - top_guard, - key_type_decl, - value_type_decl, - accessor_type_decl, - hashmap_decl, - create_hashmap_decl, - destroy_hashmap_decl, - hashmap_get_decl, - hashmap_endget_decl, - hashmap_push_decl, - hashmap_remove_decl, - bottom_guard - ) != 0 - ) { - fprintf(stderr, "Couldn't generate header file: error writing to file: %s\n", header_filename->data); - exit(EXIT_FAILURE); + { + FILE* source; + if( + !(source = fopen(source_filename->data, "w")) + ) { + char* m = source_filename->data; + fprintf(stderr, "Couldn't open source file: %s\n", source_filename->data); + exit(EXIT_FAILURE); + } + if( + tstring_n_write( + source,21, + top_guard, + cpp_header_include, + extc_top_guard, + key_type_decl, + value_type_decl, + accessor_type_decl, + hash_decl, + hashmap_decl, + + create_hashmap_decl, + destroy_hashmap_decl, + hashmap_get_decl, + hashmap_endget_decl, + hashmap_push_decl, + hashmap_remove_decl, + + create_hashmap_impl, + destroy_hashmap_impl, + hashmap_get_impl, + hashmap_endget_impl, + hashmap_push_impl, + hashmap_remove_impl, + extc_bottom_guard, + bottom_guard + ) != 0 + ) { + fprintf(stderr, "Couldn't generate header file: error writing to file: %s\n", source_filename->data); + exit(EXIT_FAILURE); + } + fclose(source); } -} \ No newline at end of file +} diff --git a/generator/src/main.c b/generator/src/main.c index e61b630..4d2a24c 100644 --- a/generator/src/main.c +++ b/generator/src/main.c @@ -2,6 +2,7 @@ void generator( tstring* header_filename, + tstring* source_filename, tstring* prefix, tstring* bucket_count, tstring* K_size, tstring* K_comp_pred, tstring* K_hash_func, @@ -11,6 +12,7 @@ void generator( int main() { generator( cstring_to_tstring("./generated_header.h"), + cstring_to_tstring("./generated_source.cpp"), cstring_to_tstring("test"), cstring_to_tstring("8000"), cstring_to_tstring("8"), diff --git a/generator/src/tstring.c b/generator/src/tstring.c index adda2af..57e3a78 100644 --- a/generator/src/tstring.c +++ b/generator/src/tstring.c @@ -112,6 +112,7 @@ tstring* tstring_n_compose(const char* count, ...) { tot_sz += strlen(va_arg(strs, char*)); break; default: + fprintf(stderr, "Invalid tstring concatenation"); va_end(strs); exit(EXIT_FAILURE); break; @@ -139,7 +140,8 @@ tstring* tstring_n_compose(const char* count, ...) { } break; default: - perror("Invalid tstring concatenation"); + fprintf(stderr, "Invalid tstring concatenation"); + va_end(strs); exit(EXIT_FAILURE); break; } @@ -151,4 +153,4 @@ tstring* tstring_n_compose(const char* count, ...) { void tstring_destroy(tstring* del) { free(del); -} \ No newline at end of file +}