diff options
author | Claudius "keldu" Holeksa <mail@keldu.de> | 2024-03-26 17:18:20 +0100 |
---|---|---|
committer | Claudius "keldu" Holeksa <mail@keldu.de> | 2024-03-26 17:18:20 +0100 |
commit | cdd8dab6d276d8b62b025ac98e495a258331d1e6 (patch) | |
tree | 4746bbd5a15e1327b1c49dfaeb5b44f594282f56 /modules | |
parent | 1beffbce27a2beb4528a80d32bdab1b65ef6654f (diff) |
tools: Breaking the C transpilation into multiple strings.
Diffstat (limited to 'modules')
-rw-r--r-- | modules/tools/c++/c_gen_iface.hpp | 136 |
1 files changed, 96 insertions, 40 deletions
diff --git a/modules/tools/c++/c_gen_iface.hpp b/modules/tools/c++/c_gen_iface.hpp index 7ee4613..15d9497 100644 --- a/modules/tools/c++/c_gen_iface.hpp +++ b/modules/tools/c++/c_gen_iface.hpp @@ -5,9 +5,10 @@ #include <forstio/codec/schema_stringify.hpp> #include <forstio/templates.hpp> +#include <map> #include <string> #include <sstream> -#include <map> +#include <vector> #include <iostream> @@ -112,20 +113,26 @@ struct language_binding_state { std::string type; }; std::map<uint32_t, language_binding_state::info> hashes; + + struct transpiled_element { + uint32_t crc32; + std::string header; + std::string source; + }; + std::vector<language_binding_state::transpiled_element> tp_elements; }; struct lang_bind_helper { - static error_or<void> append_string(buffer& buff, const std::string_view& str){ - for(uint64_t i = 0; i < str.size(); ++i){ - auto err = buff.push(static_cast<uint8_t>(str[i])); - if(!err.template is_type<err::no_error>()){ - return err; - } + static error_or<void> append_string(std::string& buff, const std::string_view& str){ + try { + buff += str; + }catch(const std::exception&){ + return make_error<err::out_of_memory>(); } return void_t{}; } - static error_or<void> append_hashed_type(buffer& buff, const std::string_view& prefix, uint32_t hash){ + static error_or<void> append_hashed_type(std::string& buff, const std::string_view& prefix, uint32_t hash){ { auto eov = append_string(buff, prefix); if(eov.is_error()){ @@ -159,7 +166,8 @@ template<typename T, uint64_t L> struct lang_bind<schema::Primitive<T,L>, binding::SyncC> { using Schema = schema::Primitive<T,L>; - static error_or<void> generate_c_to_cpp(buffer& src, const language_binding_config& cfg, language_binding_state& state, const std::string_view& cpp_name, const std::string_view& c_name ){ + static error_or<void> generate_c_to_cpp(const language_binding_config& cfg, language_binding_state& state, const std::string_view& cpp_name, const std::string_view& c_name ){ + return void_t{}; { auto eov = lang_bind_helper::append_string(src, "\t"); if(eov.is_error()){ @@ -230,12 +238,19 @@ struct lang_bind<schema::Primitive<T,L>, binding::SyncC> { } static error_or<void> generate(buffer& head, buffer& src, const language_binding_config& cfg, language_binding_state& state){ - constexpr uint64_t hash = schema_hash<Schema>::apply(); + constexpr uint32_t hash = schema_hash<Schema>::apply(); { std::string hash_type_str = cfg.prefix + "_" + std::to_string(hash) + "_t"; auto emp = state.hashes.emplace(std::make_pair(hash, hash_type_str)); if(emp.second){ + try { + language_binding_state::transpiled_element ele; + ele.crc32 = hash; + state.tp_elements.emplace_back(ele); + }catch(const std::exception&){ + return make_error<err::out_of_memory>(); + } { auto eov = lang_bind_helper::append_string(head, "typedef "); if(eov.is_error()){ @@ -276,28 +291,61 @@ struct lang_bind<schema::Primitive<T,L>, binding::SyncC> { template<typename... V, string_literal... K> struct lang_bind<schema::Struct<schema::Member<V,K>...>, binding::SyncC> { using Schema = schema::Struct<schema::Member<V,K>...>; + + static error_or<void> generate_c_to_cpp(buffer& src, const language_binding_config& cfg, language_binding_state& state, const std::string_view& cpp_name, const std::string_view& c_name ){ + return void_t{}; + } + + static error_or<void> generate_cpp_to_c(buffer& src, const language_binding_config& cfg, language_binding_state& state, const std::string_view& c_name, const std::string_view& cpp_name ){ + return void_t{}; + } template<uint64_t i> - static error_or<void> generate_ele(buffer& head, buffer& src, const language_binding_config& cfg, language_binding_state& state){ + static error_or<void> guarantee_ele(buffer& head, buffer& src, const language_binding_config& cfg, language_binding_state& state){ using MT = typename parameter_pack_type<i,V...>::type; - constexpr uint64_t hash = schema_hash<MT>::apply(); - std::string hash_type_str = cfg.prefix + "_" + std::to_string(hash) + "_t"; - auto emp = state.hashes.emplace(std::make_pair(hash, hash_type_str)); /** - * If successful insertion did happen that means we have no struct def yet. + * Guarante existance of inner type */ - if (emp.second) { - { - auto eov = lang_bind_helper::append_hashed_type(head, cfg.prefix, hash); + { + auto eov = lang_bind<MT, binding::SyncC>::generate(head, src, cfg, state); if(eov.is_error()){ return eov; } + } + if constexpr ( (i+1) < sizeof...(V) ){ + return guarantee_ele<i+1u>(head, src, cfg, state); + } + return void_t{}; + } + + template<uint64_t i> + static error_or<void> generate_ele(buffer& head, buffer& src, const language_binding_config& cfg, language_binding_state& state){ + using MT = typename parameter_pack_type<i,V...>::type; + static constexpr string_literal Lit = parameter_key_pack_type<i,K...>::literal; + + constexpr uint64_t hash = schema_hash<MT>::apply(); + { + auto eov = lang_bind_helper::append_hashed_type(head, cfg.prefix, hash); + if(eov.is_error()){ + return eov; } - { - auto eov = lang_bind_helper::append_string(head, "};\n"); - if(eov.is_error()){ - return eov; - } + } + { + auto eov = lang_bind_helper::append_string(head, " "); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(head, Lit.view()); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(head, ";\n"); + if(eov.is_error()){ + return eov; } } @@ -320,6 +368,12 @@ struct lang_bind<schema::Struct<schema::Member<V,K>...>, binding::SyncC> { /** * Generate struct type */ + if constexpr ( sizeof...(V) > 0){ + auto eov = guarantee_ele<0u>(head, src, cfg, state); + if(eov.is_error()){ + return eov; + } + } { auto eov = lang_bind_helper::append_string(head, "struct "); if(eov.is_error()){ @@ -342,7 +396,7 @@ struct lang_bind<schema::Struct<schema::Member<V,K>...>, binding::SyncC> { auto eov = generate_ele<0>(head, src, cfg, state); } { - auto eov = lang_bind_helper::append_string(head, "\n};\n"); + auto eov = lang_bind_helper::append_string(head, "};\n"); if(eov.is_error()){ return eov; } @@ -361,10 +415,12 @@ struct lang_bind<schema::Array<T,D>, binding::SyncC> { static_assert(is_primitive<T>::value, "Currently only primitive type arrays are supported"); static error_or<void> generate_c_to_cpp(buffer& src, const language_binding_config& cfg, language_binding_state& state, const std::string_view& cpp_name, const std::string_view& c_name ){ + return void_t{}; return make_error<err::not_implemented>(); } static error_or<void> generate_cpp_to_c(buffer& src, const language_binding_config& cfg, language_binding_state& state, const std::string_view& c_name, const std::string_view& cpp_name ){ + return void_t{}; return make_error<err::not_implemented>(); } @@ -786,25 +842,25 @@ struct lang_bind<schema::Function<Input, Output>, binding::SyncC> { template<typename... M> struct lang_bind<schema::Interface<M...>, binding::SyncC> { template<uint64_t i> - static error_or<void> generate_element(buffer& buff, buffer& src, const language_binding_config& cfg, language_binding_state& state){ + static error_or<void> generate_element(const language_binding_config& cfg, language_binding_state& state){ using Member = typename parameter_pack_type<i, M...>::type; using MValue = typename Member::ValueType; static constexpr string_literal MKey = Member::KeyLiteral; { - auto eov = lang_bind<MValue, binding::SyncC>::generate(buff, src, cfg, state, MKey.view()); + auto eov = lang_bind<MValue, binding::SyncC>::generate(cfg, state, MKey.view()); if(eov.is_error()){ return eov; } } if constexpr ((i+1) < sizeof...(M) ){ - return generate_element<i+1>(buff, src, cfg, state); + return generate_element<i+1>(cfg, state); } return void_t{}; } - static error_or<void> generate(buffer& buff, buffer& src, const language_binding_config& cfg){ + static error_or<void> generate(buffer& head, buffer& src, const language_binding_config& cfg){ if(cfg.prefix.size() == 0){ return make_error<err::invalid_state>("C interfaces need a prefix."); } @@ -851,21 +907,21 @@ struct lang_bind<schema::Interface<M...>, binding::SyncC> { * Context definition */ /// @todo Add Macro which reduces typing time ? Not really that much shorter :/ - // SAW_CALL_AND_RETURN_ON_ERROR(lang_bind_helper::append_string(buff, "struct ")); + // SAW_CALL_AND_RETURN_ON_ERROR(lang_bind_helper::append_string(head, "struct ")); { - auto eov = lang_bind_helper::append_string(buff, "struct "); + auto eov = lang_bind_helper::append_string(head, "struct "); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(buff, cfg.prefix); + auto eov = lang_bind_helper::append_string(head, cfg.prefix); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(buff, "_context {\n\tvoid* ctx;\n};\n\n"); + auto eov = lang_bind_helper::append_string(head, "_context {\n\tvoid* ctx;\n};\n\n"); if(eov.is_error()){ return eov; } @@ -875,43 +931,43 @@ struct lang_bind<schema::Interface<M...>, binding::SyncC> { */ auto ctx_func = [&](std::string_view str) -> error_or<void>{ { - auto eov = lang_bind_helper::append_string(buff, "int "); + auto eov = lang_bind_helper::append_string(head, "int "); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(buff, cfg.prefix); + auto eov = lang_bind_helper::append_string(head, cfg.prefix); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(buff, "_context_"); + auto eov = lang_bind_helper::append_string(head, "_context_"); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(buff, str); + auto eov = lang_bind_helper::append_string(head, str); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(buff, " ( "); + auto eov = lang_bind_helper::append_string(head, " ( "); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(buff, cfg.prefix); + auto eov = lang_bind_helper::append_string(head, cfg.prefix); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(buff, "_context* ctx );\n\n"); + auto eov = lang_bind_helper::append_string(head, "_context* ctx );\n\n"); if(eov.is_error()){ return eov; } @@ -968,7 +1024,7 @@ struct lang_bind<schema::Interface<M...>, binding::SyncC> { } if constexpr (sizeof...(M) > 0){ - return generate_element<0>(buff, src, cfg, state); + return generate_element<0>(head, src, cfg, state); } return void_t{}; |