summaryrefslogtreecommitdiff
path: root/modules/tools
diff options
context:
space:
mode:
Diffstat (limited to 'modules/tools')
-rw-r--r--modules/tools/c++/c_gen_iface.hpp218
-rw-r--r--modules/tools/tests/c_iface.cpp18
2 files changed, 207 insertions, 29 deletions
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;
}
-*/
}