From 3be0c08510661cdca813cc5f1f471450c2ef3ce5 Mon Sep 17 00:00:00 2001 From: "Claudius \"keldu\" Holeksa" Date: Mon, 18 Mar 2024 16:45:15 +0100 Subject: tools: Generating C interface sources for primitives --- modules/tools/c++/c_gen_iface.hpp | 290 ++++++++++++++++++++++++++++++++++---- 1 file changed, 264 insertions(+), 26 deletions(-) (limited to 'modules/tools/c++/c_gen_iface.hpp') diff --git a/modules/tools/c++/c_gen_iface.hpp b/modules/tools/c++/c_gen_iface.hpp index 8eb0bca..7dc1197 100644 --- a/modules/tools/c++/c_gen_iface.hpp +++ b/modules/tools/c++/c_gen_iface.hpp @@ -158,6 +158,76 @@ struct lang_bind_helper { template struct lang_bind, binding::SyncC> { using Schema = schema::Primitive; + + static error_or 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 ){ + { + auto eov = lang_bind_helper::append_string(src, "\t"); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(src, cpp_name); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(src, ".set(*"); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(src, c_name); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(src, ");\n"); + if(eov.is_error()){ + return eov; + } + } + return void_t{}; + } + + static error_or generate_cpp_to_c(buffer& src, const language_binding_config& cfg, language_binding_state& state, const std::string_view& cpp_name, const std::string_view& c_name ){ + + { + auto eov = lang_bind_helper::append_string(src, "\t*"); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(src, c_name); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(src, " = "); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(src, cpp_name); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(src, ".get();\n"); + if(eov.is_error()){ + return eov; + } + } + + return void_t{}; + } static error_or generate(buffer& buff, buffer& src, const language_binding_config& cfg, language_binding_state& state){ constexpr uint64_t hash = schema_hash::apply(); @@ -209,6 +279,14 @@ struct lang_bind, binding::SyncC> { static_assert(is_primitive::value, "Currently only primitive type arrays are supported"); + static error_or 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 make_error(); + } + + static error_or 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 make_error(); + } + static error_or generate(buffer& buff, buffer& src, const language_binding_config& cfg, language_binding_state& state){ constexpr uint64_t hash = schema_hash::apply(); @@ -381,62 +459,136 @@ struct lang_bind, binding::SyncC> { constexpr uint64_t output_hash = schema_hash::apply(); /** - * Function generations + * Source */ { - auto eov = lang_bind::generate(buff, src, cfg, state); - if(eov.is_error()){ - return eov; - } + auto eov = append_function_def(src, cfg, state, f_name); + if(eov.is_error()){ + return eov; + } } { - auto eov = lang_bind::generate(buff, src, cfg, state); - if(eov.is_error()){ - return eov; + auto eov = lang_bind_helper::append_string(src, "{\n\tif(!ctx || !(ctx->ctx)) return -1;\n\tif(!input) return -1;\n\tif(!output) return -1;\n"); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(src, "\n\tauto& iface = "); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(src, cfg.prefix); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(src, "_get_cpp_interface_priv(*ctx);\n\t"); + if(eov.is_error()){ + return eov; + } + } + /** + * Check declarations and definitions. + * Translate input. + */ + { + auto eov = lang_bind_helper::append_string(src, "saw::data<"); + if(eov.is_error()){ + return eov; + } + } + { + std::stringstream ss; + try{ + { + schema_stringify::apply(ss); + auto eov = lang_bind_helper::append_string(src, ss.str()); + if(eov.is_error()){ + return eov; + } } + }catch(const std::exception&){ + return make_error(); + } } { - auto eov = lang_bind_helper::append_string(buff, "typedef "); + auto eov = lang_bind_helper::append_string(src, "> cpp_input_root;\n"); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_hashed_type(buff, cfg.prefix, schema_hash::apply()); + auto eov = lang_bind::generate(buff, src, cfg, state); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(buff, " "); + auto eov = lang_bind::generate_c_to_cpp(src, cfg, state, "c_input_root", "cpp_input_root"); if(eov.is_error()){ return eov; } } + /** + * Call the c++ implementation + */ { - auto eov = lang_bind_helper::append_string(buff, cfg.prefix); + auto eov = lang_bind_helper::append_string(src, "\n\tauto eov = iface.template call<\""); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(buff, "_"); + auto eov = lang_bind_helper::append_string(src, f_name); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(buff, f_name); + auto eov = lang_bind_helper::append_string(src, "\">(std::move(cpp_input_root));\n"); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(buff, "_input_t;\n"); + auto eov = lang_bind_helper::append_string(src, "\tif(eov.is_error()){\n\t\tauto& err = eov.get_error();\n\t\treturn err.get_code();\n\t}\n\tauto& cpp_output_root = eov.get_value();\n\n"); if(eov.is_error()){ return eov; } } + { + auto eov = lang_bind::generate_cpp_to_c(src, cfg, state, "cpp_output_root", "c_output_root"); + if(eov.is_error()){ + return eov; + } + } + + /** + * Check declarations and definitions. + * Translate output. + */ + { + auto eov = lang_bind::generate(buff, src, cfg, state); + if(eov.is_error()){ + return eov; + } + } + /** + * End source declaration + */ + { + auto eov = lang_bind_helper::append_string(src, "\treturn 0;\n}\n\n"); + if(eov.is_error()){ + return eov; + } + } + /** + * Header + */ { auto eov = lang_bind_helper::append_string(buff, "typedef "); if(eov.is_error()){ @@ -444,7 +596,7 @@ struct lang_bind, binding::SyncC> { } } { - auto eov = lang_bind_helper::append_hashed_type(buff, cfg.prefix, schema_hash::apply()); + auto eov = lang_bind_helper::append_hashed_type(buff, cfg.prefix, schema_hash::apply()); if(eov.is_error()){ return eov; } @@ -474,46 +626,64 @@ struct lang_bind, binding::SyncC> { } } { - auto eov = lang_bind_helper::append_string(buff, "_output_t;\n"); + auto eov = lang_bind_helper::append_string(buff, "_input_t;\n"); if(eov.is_error()){ return eov; } } { - auto eov = append_function_def(buff, cfg, state, f_name); + auto eov = lang_bind_helper::append_string(buff, "typedef "); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(buff, ";\n\n"); + auto eov = lang_bind_helper::append_hashed_type(buff, cfg.prefix, schema_hash::apply()); if(eov.is_error()){ return eov; } } - /** - * Source - */ { - auto eov = append_function_def(src, cfg, state, f_name); + auto eov = lang_bind_helper::append_string(buff, " "); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(buff, cfg.prefix); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(src, "{\n\tif(!ctx) return -1;\n\tif(!input) return -1;\n\tif(!output) return -1;\n\t"); + auto eov = lang_bind_helper::append_string(buff, "_"); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(buff, f_name); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(src, ""); + auto eov = lang_bind_helper::append_string(buff, "_output_t;\n"); if(eov.is_error()){ return eov; } } + /** + * Function generations + */ { - auto eov = lang_bind_helper::append_string(src, "return 0;\n}\n\n"); + auto eov = append_function_def(buff, cfg, state, f_name); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(buff, ";\n\n"); if(eov.is_error()){ return eov; } @@ -553,6 +723,40 @@ struct lang_bind, binding::SyncC> { /** * Setup context creation to bind interface to a context */ + /** + * Interface type helper + */ + { + auto eov = lang_bind_helper::append_string(src, "namespace {\nnamespace schema {\n"); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(src, "using InterfaceType = "); + if(eov.is_error()){ + return eov; + } + } + { + std::stringstream ss; + schema_stringify>::apply(ss); + try { + auto eov = lang_bind_helper::append_string(src, ss.str()); + if(eov.is_error()){ + return eov; + } + }catch(const std::exception&){ + return make_error("No memory after stringification"); + } + } + { + auto eov = lang_bind_helper::append_string(src, ";\n}\n}\n\n"); + if(eov.is_error()){ + return eov; + } + } + /** * Context definition */ @@ -639,6 +843,40 @@ struct lang_bind, binding::SyncC> { } } + /** + * Create a casting helper in sources for the interface type + */ + { + auto eov = lang_bind_helper::append_string(src, "saw::interface<>& "); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(src, cfg.prefix); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(src, "_get_cpp_interface_priv("); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(src, cfg.prefix); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(src, "& ctx){\n\treturn *reinterpret_cast*>(ctx.ctx);\n}\n\n"); + if(eov.is_error()){ + return eov; + } + } + if constexpr (sizeof...(M) > 0){ return generate_element<0>(buff, src, cfg, state); } -- cgit v1.2.3