diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/tools/c++/c_gen_iface.hpp | 198 |
1 files changed, 160 insertions, 38 deletions
diff --git a/modules/tools/c++/c_gen_iface.hpp b/modules/tools/c++/c_gen_iface.hpp index ebbf5f7..96e8060 100644 --- a/modules/tools/c++/c_gen_iface.hpp +++ b/modules/tools/c++/c_gen_iface.hpp @@ -157,6 +157,129 @@ struct lang_bind_helper { return void_t{}; } + template<typename Schema> + static error_or<void> append_translation_func(std::string& buff, const std::string_view& prefix, bool c_to_cpp){ + constexpr uint32_t hash = schema_hash<Schema>::apply(); + { + auto eov = lang_bind_helper::append_string(buff, "saw::error_or<void> "); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_hashed_type(buff, prefix, hash); + if(eov.is_error()){ + return eov; + } + } + { + std::string_view trans = c_to_cpp ? "_translate_c_to_cpp" : "_translate_cpp_to_c"; + auto eov = lang_bind_helper::append_string(buff, trans); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(buff, "( const "); + if(eov.is_error()){ + return eov; + } + } + + std::string hash_type_str = std::string{prefix} + "_" + std::to_string(hash) + "_t"; + /** + * Lambdas + */ + auto c_val = [&]() -> error_or<void>{ + { + auto eov = lang_bind_helper::append_string(buff, hash_type_str); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(buff, "* c_val"); + if(eov.is_error()){ + return eov; + } + } + return void_t{}; + }; + auto cpp_val = [&]() -> error_or<void> { + { + auto eov = lang_bind_helper::append_string(buff, "saw::data<"); + if(eov.is_error()){ + return eov; + } + } + { + std::stringstream ss; + try{ + { + schema_stringify<Schema>::apply(ss); + auto eov = lang_bind_helper::append_string(buff, ss.str()); + if(eov.is_error()){ + return eov; + } + } + }catch(const std::exception&){ + return make_error<err::out_of_memory>(); + } + } + { + auto eov = lang_bind_helper::append_string(buff, ">& cpp_val"); + if(eov.is_error()){ + return eov; + } + } + return void_t{}; + }; + if(c_to_cpp){ + { + auto eov = c_val(); + if(eov.is_error()){ + return eov; + } + } + }else{ + { + auto eov = cpp_val(); + if(eov.is_error()){ + return eov; + } + } + } + { + auto eov = lang_bind_helper::append_string(buff, ", "); + if(eov.is_error()){ + return eov; + } + } + if(!c_to_cpp){ + { + auto eov = c_val(); + if(eov.is_error()){ + return eov; + } + } + }else{ + { + auto eov = cpp_val(); + if(eov.is_error()){ + return eov; + } + } + } + { + auto eov = lang_bind_helper::append_string(buff, " )"); + if(eov.is_error()){ + return eov; + } + } + + return void_t{}; + } + static error_or<void> append_hashed_type(std::string& buff, const std::string_view& prefix, uint32_t hash){ { auto eov = append_string(buff, prefix); @@ -316,73 +439,42 @@ struct lang_bind<schema::Primitive<T,L>, binding::SyncC> { * Translation in source */ { - auto eov = lang_bind_helper::append_string(tpe.at(id).source, "namespace {\nsaw::error_or<void> "); - if(eov.is_error()){ - return eov; - } - } - { - auto eov = lang_bind_helper::append_hashed_type(tpe.at(id).source, cfg.prefix, hash); - if(eov.is_error()){ - return eov; - } - } - { - auto eov = lang_bind_helper::append_string(tpe.at(id).source, "_translate_c_to_cpp ( "); - if(eov.is_error()){ - return eov; - } - } - { - auto eov = lang_bind_helper::append_string(tpe.at(id).source, " const "); + auto eov = lang_bind_helper::append_string(tpe.at(id).source, "namespace {\n"); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(tpe.at(id).source, hash_type_str); + auto eov = lang_bind_helper::append_translation_func<Schema>(tpe.at(id).source, cfg.prefix, true); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(tpe.at(id).source, "* c_input, saw::data<"); + auto eov = lang_bind_helper::append_string(tpe.at(id).source, " {\n\tcpp_output.set(*c_input);\n"); if(eov.is_error()){ return eov; } } { - std::stringstream ss; - try{ - { - schema_stringify<Schema>::apply(ss); - auto eov = lang_bind_helper::append_string(tpe.at(id).source, ss.str()); - if(eov.is_error()){ - return eov; - } - } - }catch(const std::exception&){ - return make_error<err::out_of_memory>(); - } - } - { - auto eov = lang_bind_helper::append_string(tpe.at(id).source, ">& cpp_output) {\n\t"); + auto eov = lang_bind_helper::append_string(tpe.at(id).source, "\treturn void_t{};\n}\n"); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(tpe.at(id).source, "cpp_output.set(*c_input);\n"); + auto eov = lang_bind_helper::append_translation_func<Schema>(tpe.at(id).source, cfg.prefix, false); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(tpe.at(id).source, "\n\treturn void_t{};\n}\n}\n"); + auto eov = lang_bind_helper::append_string(tpe.at(id).source, " {\n\t*c_output = cpp_output.get();\n\treturn void_t{};\n}\n}"); if(eov.is_error()){ return eov; } } + } } @@ -437,6 +529,9 @@ struct lang_bind<schema::Struct<schema::Member<V,K>...>, binding::SyncC> { } } /** + * Generate translation element + */ + /** * Ensure generation of dependent types */ { @@ -492,6 +587,33 @@ struct lang_bind<schema::Struct<schema::Member<V,K>...>, binding::SyncC> { return eov; } } + /** + * Generate translation element + */ + { + auto eov = lang_bind_helper::append_string(tpe.at(id).header, "namespace {\n"); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = generate_translation_func(tpe.at(id).source, cfg.prefix, true); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = generate_translation_func(tpe.at(id).source, cfg.prefix, false); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(tpe.at(id).header, "}\n"); + if(eov.is_error()){ + return eov; + } + } if constexpr ( sizeof...(V) > 0 ) { auto eov = generate_ele<0>(cfg, state, id); } |