diff options
author | Claudius "keldu" Holeksa <mail@keldu.de> | 2024-03-18 16:45:15 +0100 |
---|---|---|
committer | Claudius "keldu" Holeksa <mail@keldu.de> | 2024-03-18 16:45:15 +0100 |
commit | 3be0c08510661cdca813cc5f1f471450c2ef3ce5 (patch) | |
tree | a14ebacc4c4397870862b5f9f1b145abe1a336e1 /modules/tools | |
parent | 0906dff296214bbff9f0e08a3bebc8c58758aa3f (diff) |
tools: Generating C interface sources for primitives
Diffstat (limited to 'modules/tools')
-rw-r--r-- | modules/tools/c++/c_gen_iface.hpp | 290 |
1 files changed, 264 insertions, 26 deletions
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<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 ){ + { + 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<void> 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<void> generate(buffer& buff, buffer& src, const language_binding_config& cfg, language_binding_state& state){ constexpr uint64_t hash = schema_hash<Schema>::apply(); @@ -209,6 +279,14 @@ 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 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 make_error<err::not_implemented>(); + } + static error_or<void> generate(buffer& buff, buffer& src, const language_binding_config& cfg, language_binding_state& state){ constexpr uint64_t hash = schema_hash<Schema>::apply(); @@ -381,70 +459,144 @@ struct lang_bind<schema::Function<Input, Output>, binding::SyncC> { constexpr uint64_t output_hash = schema_hash<Output>::apply(); /** - * Function generations + * Source */ { - auto eov = lang_bind<Input, binding::SyncC>::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<Output, binding::SyncC>::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<Input>::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<err::out_of_memory>(); + } } { - 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<Input>::apply()); + auto eov = lang_bind<Input, binding::SyncC>::generate(buff, src, cfg, state); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(buff, " "); + auto eov = lang_bind<Input, binding::SyncC>::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<Input, binding::SyncC>::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<Output, binding::SyncC>::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()){ return eov; } } { - auto eov = lang_bind_helper::append_hashed_type(buff, cfg.prefix, schema_hash<Output>::apply()); + auto eov = lang_bind_helper::append_hashed_type(buff, cfg.prefix, schema_hash<Input>::apply()); if(eov.is_error()){ return eov; } @@ -474,46 +626,64 @@ struct lang_bind<schema::Function<Input, Output>, 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<Output>::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; } @@ -554,6 +724,40 @@ struct lang_bind<schema::Interface<M...>, 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<schema::Interface<M...>>::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<err::out_of_memory>("No memory after stringification"); + } + } + { + auto eov = lang_bind_helper::append_string(src, ";\n}\n}\n\n"); + if(eov.is_error()){ + return eov; + } + } + + /** * Context definition */ /// @todo Add Macro which reduces typing time ? Not really that much shorter :/ @@ -639,6 +843,40 @@ struct lang_bind<schema::Interface<M...>, 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<saw::interface<schema::InterfaceType>*>(ctx.ctx);\n}\n\n"); + if(eov.is_error()){ + return eov; + } + } + if constexpr (sizeof...(M) > 0){ return generate_element<0>(buff, src, cfg, state); } |