diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/codec/c++/schema.hpp | 3 | ||||
-rw-r--r-- | modules/codec/c++/schema_hash.hpp | 20 | ||||
-rw-r--r-- | modules/tools/c++/c_gen_iface.hpp | 218 | ||||
-rw-r--r-- | modules/tools/tests/c_iface.cpp | 18 |
4 files changed, 224 insertions, 35 deletions
diff --git a/modules/codec/c++/schema.hpp b/modules/codec/c++/schema.hpp index 5348cfe..82fc0a5 100644 --- a/modules/codec/c++/schema.hpp +++ b/modules/codec/c++/schema.hpp @@ -116,6 +116,9 @@ using VarLong = VariableLengthPrimitive<SignedInteger, 10>; template <class Request, class Response> struct Function { static constexpr string_literal name = "Function"; + + using RequestT = Request; + using ResponseT = Response; }; template <class... T> struct Interface { diff --git a/modules/codec/c++/schema_hash.hpp b/modules/codec/c++/schema_hash.hpp index 90ab208..5e44497 100644 --- a/modules/codec/c++/schema_hash.hpp +++ b/modules/codec/c++/schema_hash.hpp @@ -125,6 +125,18 @@ struct schema_hash_seed<schema::Tuple<T...>> { } }; +template<typename V, string_literal K> +struct schema_hash_seed<schema::Member<V,K>> { + using Schema = schema::Member<V,K>; + + static constexpr uint32_t apply(uint32_t seed){ + seed = hash_literal<Schema::name>::apply(seed); + seed = schema_hash_seed<V>::apply(seed); + seed = hash_literal<K>::apply(seed); + return seed; + } +}; + template<typename... V, string_literal... K> struct schema_hash_seed<schema::Struct<schema::Member<V,K>...>> { using Schema = schema::Struct<schema::Member<V,K>...>; @@ -135,9 +147,7 @@ struct schema_hash_seed<schema::Struct<schema::Member<V,K>...>> { constexpr string_literal Lit = parameter_key_pack_type<i,K...>::literal; using MemberT = typename parameter_pack_type<i,schema::Member<V,K>...>::type; - seed = hash_literal<MemberT::name>::apply(seed); - seed = schema_hash_seed<Type>::apply(seed); - seed = hash_literal<Lit>::apply(seed); + seed = schema_hash_seed<MemberT>::apply(seed); if constexpr ( (i+1) < sizeof...(V) ){ return apply_ele<i+1>(seed); @@ -176,9 +186,7 @@ struct schema_hash_seed<schema::Interface<schema::Member<T, Names>...>> { constexpr string_literal Lit = parameter_key_pack_type<i,Names...>::literal; using MemberT = schema::Member<Type,Lit>; - seed = hash_literal<MemberT::name>::apply(seed); - seed = schema_hash_seed<Type>::apply(seed); - seed = hash_literal<Lit>::apply(seed); + seed = schema_hash_seed<MemberT>::apply(seed); if constexpr ( (i+1) < sizeof...(T) ){ return apply_ele<i+1>(seed); diff --git a/modules/tools/c++/c_gen_iface.hpp b/modules/tools/c++/c_gen_iface.hpp index 2dfa36f..7c26f80 100644 --- a/modules/tools/c++/c_gen_iface.hpp +++ b/modules/tools/c++/c_gen_iface.hpp @@ -151,6 +151,7 @@ struct lang_bind_helper { } }; + template<typename T, uint64_t L> struct lang_bind<schema::Primitive<T,L>, binding::C> { using Schema = schema::Primitive<T,L>; @@ -199,9 +200,84 @@ struct lang_bind<schema::Primitive<T,L>, binding::C> { } }; +template<typename T, uint64_t D> +struct lang_bind<schema::Array<T,D>, binding::C> { + using Schema = schema::Array<T,D>; + + static_assert(is_primitive<T>::value, "Currently only primitive type arrays are supported"); + + static error_or<void> generate(buffer& buff, const language_binding_config& cfg, language_binding_state& state){ + constexpr uint64_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){ + { + auto eov = lang_bind<schema::UInt64, binding::C>::generate(buff, cfg, state); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind<T, binding::C>::generate(buff, cfg, state); + if(eov.is_error()){ + return eov; + } + } + + { + auto eov = lang_bind_helper::append_string(buff, "struct "); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_hashed_type(buff, cfg.prefix, hash); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(buff, " {\n\t"); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_hashed_type(buff, cfg.prefix, schema_hash<T>::apply()); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(buff, "* data;\n\t"); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_hashed_type(buff, cfg.prefix, schema_hash<schema::UInt64>::apply()); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(buff, " length;\n};\n"); + if(eov.is_error()){ + return eov; + } + } + } + + return void_t{}; + } +}; + template<typename Input, typename Output> struct lang_bind<schema::Function<Input, Output>, binding::C> { - static error_or<void> generate(buffer& buff, const language_binding_config& cfg, language_binding_state& state){ + static error_or<void> append_function_def(buffer& buff, + + static error_or<void> generate(buffer& buff, buffer& src, const language_binding_config& cfg, language_binding_state& state, const std::string_view& f_name){ constexpr uint64_t input_hash = schema_hash<Input>::apply(); constexpr uint64_t output_hash = schema_hash<Output>::apply(); @@ -217,26 +293,66 @@ struct lang_bind<schema::Function<Input, Output>, binding::C> { return eov; } } - - return void_t{}; - } -}; - -template<typename... M> -struct lang_bind<schema::Interface<M...>, binding::C> { - template<uint64_t i> - static error_or<void> generate_element(buffer& buff, 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::C>::generate(buff, cfg, state); + 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<Input>::apply()); + if(eov.is_error()){ + return eov; + } + } + { + 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(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(buff, "_input_t;\n"); + if(eov.is_error()){ + return eov; + } + } + { + 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()); + if(eov.is_error()){ + return eov; + } + } + { + 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()){ @@ -250,31 +366,86 @@ struct lang_bind<schema::Interface<M...>, binding::C> { } } { - auto eov = lang_bind_helper::append_string(buff, MKey.view()); + auto eov = lang_bind_helper::append_string(buff, f_name); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(buff, "_output_t;\n"); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(buff, "int "); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(buff, "("); + auto eov = lang_bind_helper::append_string(buff, cfg.prefix); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_hashed_type(buff, cfg.prefix, schema_hash<Member>::apply()); + auto eov = lang_bind_helper::append_string(buff, "_"); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(buff, ","); + auto eov = lang_bind_helper::append_string(buff, f_name); if(eov.is_error()){ return eov; } } { - auto eov = lang_bind_helper::append_string(buff, ");"); + auto eov = lang_bind_helper::append_string(buff, "( const "); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_hashed_type(buff, cfg.prefix, schema_hash<Input>::apply()); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(buff, "* input, "); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_hashed_type(buff, cfg.prefix, schema_hash<Output>::apply()); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = lang_bind_helper::append_string(buff, "* output);\n\n"); + if(eov.is_error()){ + return eov; + } + } + + return void_t{}; + } +}; + +template<typename... M> +struct lang_bind<schema::Interface<M...>, binding::C> { + template<uint64_t i> + static error_or<void> generate_element(buffer& buff, 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::C>::generate(buff, cfg, state, MKey.view()); if(eov.is_error()){ return eov; } @@ -290,6 +461,7 @@ struct lang_bind<schema::Interface<M...>, binding::C> { if(cfg.prefix.size() == 0){ return make_error<err::invalid_state>("C interfaces need a prefix."); } + language_binding_state state; if constexpr (sizeof...(M) > 0){ @@ -308,8 +480,8 @@ struct language_binding { template<typename IfaceSchema> struct language_binding<IfaceSchema, binding::C> { - static error_or<void> generate(buffer& buff, const language_binding_config& cfg){ - return impl::lang_bind<IfaceSchema, binding::C>::generate(buff, cfg); + static error_or<void> generate(buffer& buff, buffer& src, const language_binding_config& cfg){ + return impl::lang_bind<IfaceSchema, binding::C>::generate(buff, src, cfg); } }; } diff --git a/modules/tools/tests/c_iface.cpp b/modules/tools/tests/c_iface.cpp index 79d2344..61668de 100644 --- a/modules/tools/tests/c_iface.cpp +++ b/modules/tools/tests/c_iface.cpp @@ -33,7 +33,14 @@ using TestStructFunctionInterface = Interface< >; using TestArrayFunctionInterface = Interface< - Member<Function<TestStructArray, Int32>, "three"> + Member<Function<TestArray, Int32>, "three"> +>; + +using TestMultiFunctionInterface = Interface< + Member<Function<TestArray, Float32>, "foo">, + Member<Function<Float64, Int8>, "bar">, + Member<Function<UInt32, TestArray>, "baz">, + Member<Function<UInt32, Float64>, "banana"> >; } @@ -44,7 +51,7 @@ void test_generate(std::string& res){ ring_buffer r_buff{4u * 1024u * 1024u}; { - auto eov = language_binding<Schema, binding::C>::generate(r_buff, {"kel"}); + auto eov = language_binding<Schema, binding::C>::generate(r_buff, {"prefix"}); SAW_EXPECT(eov.is_value(), std::string{"Couldn't generate interface info: "} + std::string{eov.get_error().get_message()}); } @@ -67,12 +74,12 @@ SAW_TEST("CIface One Function Interface"){ test_generate<schema::TestOneFunctionInterface>(res); std::cout<<"\n"<<res<<"\n"<<std::endl; } -/* -SAW_TEST("CIface Struct Function Interface"){ + +SAW_TEST("CIface Multi Function Interface"){ using namespace saw; std::string res; - test_generate<schema::TestStructFunctionInterface>(res); + test_generate<schema::TestMultiFunctionInterface>(res); std::cout<<"\n"<<res<<"\n"<<std::endl; } @@ -83,5 +90,4 @@ SAW_TEST("CIface Array Function Interface"){ test_generate<schema::TestArrayFunctionInterface>(res); std::cout<<"\n"<<res<<"\n"<<std::endl; } -*/ } |