#include "tstring.h" #include "string.h" #include "stdlib.h" #include "stdio.h" void generator( tstring* header_filename, tstring* source_filename, tstring* prefix, tstring* bucket_count, tstring* K_size, tstring* K_comp_pred, tstring* K_hash_func, tstring* V_size ) { tstring* key_type = tstring_n_compose("tc", prefix, "_key_t" ); tstring* key_type_decl = tstring_n_compose("ctctc", "struct ", key_type, "{\n" "char* data[",K_size,"];\n" "};\n" ); tstring* value_type = tstring_n_compose("tc", prefix, "_value_t" ); tstring* value_type_decl = tstring_n_compose("ctctc", "struct ", value_type, "{\n" "char* data[",V_size,"];\n" "};\n" ); tstring* accessor_type = tstring_n_compose("tc", prefix, "_accessor_t" ); tstring* accessor_type_decl = tstring_n_compose("ctc", "struct ", accessor_type, "{\n" "void* value;\n" "};\n" ); tstring* hash_decl = tstring_n_compose("ctctctctc", "size_t ",K_hash_func,"(void*);\n" "struct ",prefix,"_hashtype{\n" "size_t operator()(const ",key_type,"& key) {\n" "return ", K_hash_func, "((void*)&key);\n" "}\n" "};\n" ); tstring* hash_type = tstring_n_compose("tc", prefix,"_hashtype" ); tstring* hashmap_ptr_type = tstring_n_compose("tc", prefix,"_hashmap_ptr" ); 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("ctctctctc", "void ", prefix, "_hm_push(",hashmap_ptr_type," ptr, ",key_type,"* k, ",value_type,"* v);\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", "void ", prefix, "_hm_endget(",accessor_type," acc);\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" ); tstring* bottom_guard = tstring_n_compose("ctc", "\n#endif // GUARD_", prefix, "\n" ); 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 mct20::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 (mct20::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); } { 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,22, 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); } }