summaryrefslogtreecommitdiff
path: root/modules/tools/c_gen_iface.hpp
diff options
context:
space:
mode:
authorClaudius "keldu" Holeksa <mail@keldu.de>2024-02-05 17:39:28 +0100
committerClaudius "keldu" Holeksa <mail@keldu.de>2024-02-05 17:39:28 +0100
commit2790590996da2f6a0f4d59570de62078a5ac8ae2 (patch)
tree526c188230bd29d5127cc13d10390b1cd134bebc /modules/tools/c_gen_iface.hpp
parent4e45bbc55c4011b919f0af8d43850748209f7f09 (diff)
tools: Move to new module structure and moving to more schema based
generation to convert more easily to json
Diffstat (limited to 'modules/tools/c_gen_iface.hpp')
-rw-r--r--modules/tools/c_gen_iface.hpp526
1 files changed, 0 insertions, 526 deletions
diff --git a/modules/tools/c_gen_iface.hpp b/modules/tools/c_gen_iface.hpp
deleted file mode 100644
index 08cf2f4..0000000
--- a/modules/tools/c_gen_iface.hpp
+++ /dev/null
@@ -1,526 +0,0 @@
-#include <forstio/error.hpp>
-#include <forstio/templates.hpp>
-#include <forstio/codec/schema.hpp>
-
-#include <string>
-#include <sstream>
-#include <map>
-
-#include <iostream>
-
-#include <forstio/codec/schema_stringify.hpp>
-
-namespace saw {
-
-namespace impl {
-namespace schema {
-using namespace saw::schema;
-
-using CVar = Struct<
- Member<schema::String, "schema">,
- Member<schema::String, "type">,
- Member<schema::String, "name">
->;
-
-using CStruct = Struct<
- Member<schema::String, "schema">,
- Member<schema::String, "name">,
- Member<Array<CVar>, "members">
->;
-
-using CFunction = Struct<
- Member<schema::String, "schema">,
- Member<schema::String, "name">,
- Member<Array<CVar>, "params">
->;
-
-using CIface = Struct<
- Member<schema::String, "schema">,
- Member<Array<CStruct>,"structs">,
- Member<Array<CFunction>,"function">
->;
-}
-/**
- * Type meant to provide future help if I decide to introduce more maps
- */
-struct c_types {
-
- struct c_member {
- std::string key;
- std::string name;
- bool is_primitive;
- };
-
- struct c_struct {
- std::string kind;
- std::string type;
- std::string cpp_schema;
- std::vector<c_member> members;
- };
-
- struct c_response {
- std::string key;
- bool is_primitive;
- };
-
- struct c_func {
- std::string cpp_schema;
- std::string cpp_name;
- c_response response;
- std::vector<c_member> requests;
- };
-
- using c_struct_map = std::map<std::string, c_struct>;
- using c_func_map = std::map<std::string, c_func>;
-
- struct state {
- std::string interface_schema;
- c_struct_map struct_map;
- c_func_map func_map;
- std::string prefix;
- std::string postfix;
- std::string encoding;
- };
-};
-
-namespace schema {
-using namespace saw::schema;
-/**
-Pseudo flattened
-using Foo = Struct<
- Member<Array<Int32>, "a">
- Member<Array<Float32>, "b">
->;
-
-Needs to be flattened to
-
-template<typename InnerSchema>
-using FlattenedSchemaElement = Struct<
- Member<Array<String>, "path">,
- Member<InnerSchema, "inner_schema">
->;
-
-// Illegal, but doable with more lines of code
-// Just use typename... T and
-// "T..." for
-// "Member<FlattenedSchemaElement<Ele>,Names>...>"
-// and specialize somewhere else
-template<typename... Ele, string_literal... Names>
-using FlattenedSchema = Struct<
- Member<String, "top_schema">,
- Member<FlattenedSchemaElement<Ele>, Names>...
->;
- */
-template<typename T, typename Res>
-struct schema_flattener {
- static_assert(always_false<T>, "Not supported");
-};
-
-template<typename T0, string_literal Name0, typename... T, string_literal... Names, typename Res>
-struct schema_flattener<schema::Struct<schema::Member<T0,Name0>,schema::Member<T,Names>...>, Res> {
-};
-
-using StructBindingSchema = Struct<
- Member<String, "kind">,
- Member<String, "key">,
- Member<String, "cpp_schema">,
- Member<Array<String>, "members">
->;
-
-using FunctionBindingSchema = Struct<
- Member<String, "cpp_schema">,
- Member<String, "name">,
- Member<String, "foo">
->;
-
-using BindingSchema = Struct<
- Member<String, "interface_schema">,
- Member<String, "prefix">,
- Member<String, "postfix">,
- Member<String, "encoding">,
- Member<Array<StructBindingSchema>, "structs">,
- Member<Array<FunctionBindingSchema>, "functions">
->;
-}
-
-/**
- * Helper to determine if we are dealing with primitive types
- */
-template<typename Schema>
-struct c_is_primitive {
- static constexpr bool value = false;
-};
-
-template<typename T, size_t N>
-struct c_is_primitive<schema::Primitive<T,N>> {
- static constexpr bool value = true;
-};
-
-template<typename Schema>
-struct c_primitive_string {
- static_assert(always_false<Schema>, "Not supported");
-};
-
-template<>
-struct c_primitive_string<schema::Int8> {
- static constexpr std::string_view value = "int8_t";
-};
-
-template<>
-struct c_primitive_string<schema::Int16> {
- static constexpr std::string_view value = "int16_t";
-};
-
-template<>
-struct c_primitive_string<schema::Int32> {
- static constexpr std::string_view value = "int32_t";
-};
-
-template<>
-struct c_primitive_string<schema::Int64> {
- static constexpr std::string_view value = "int64_t";
-};
-
-template<>
-struct c_primitive_string<schema::UInt8> {
- static constexpr std::string_view value = "uint8_t";
-};
-
-template<>
-struct c_primitive_string<schema::UInt16> {
- static constexpr std::string_view value = "uint16_t";
-};
-
-template<>
-struct c_primitive_string<schema::UInt32> {
- static constexpr std::string_view value = "uint32_t";
-};
-
-template<>
-struct c_primitive_string<schema::UInt64> {
- static constexpr std::string_view value = "uint64_t";
-};
-
-template<>
-struct c_primitive_string<schema::Float32> {
- static constexpr std::string_view value = "float";
-};
-
-template<>
-struct c_primitive_string<schema::Float64> {
- static constexpr std::string_view value = "double";
-};
-
-template<typename Schema>
-struct c_data_translater {
- static_assert(always_false<Schema>, "Not supported");
-};
-
-template<typename T, size_t N>
-struct c_data_translater<schema::Primitive<T,N>> {
- using StructMap = typename c_types::c_struct_map;
- using Schema = schema::Primitive<T,N>;
-
- static error_or<void> generate(c_types::state& c_state, std::string& str){
- (void) c_state;
- str += c_primitive_string<Schema>::value;
- return void_t{};
- }
-};
-
-template<typename T, size_t Dim>
-struct c_data_translater<schema::Array<T,Dim>> {
- using Schema = schema::Array<T,Dim>;
- using StructMap = typename c_types::c_struct_map;
-
- static error_or<void> generate(c_types::state& c_state, std::string& type_str){
- type_str = "array_";
-
- std::string inner_type_str;
- auto eov = impl::c_data_translater<T>::generate(c_state, inner_type_str);
- if(eov.is_error()){
- return eov;
- }
-
- type_str += inner_type_str;
-
- if(Dim > 1){
- type_str += "_";
- type_str += std::to_string(Dim);
- type_str += "d";
- }
-
- if(c_state.struct_map.find(type_str) != c_state.struct_map.end()){
- return void_t{};
- }
-
- c_types::c_struct str;
-
- try {
- std::stringstream iss;
- schema_stringify<Schema>::apply(iss);
- str.cpp_schema = iss.str();
- }catch(const std::exception& e){
- return make_error<err::critical>();
- }
-
- /**
- * Adding heap alloc data ptr
- */
- {
- c_types::c_member memb;
- memb.key = inner_type_str;
- memb.name = "data";
- memb.is_primitive = c_is_primitive<T>::value;
- // fn.members.emplace_back(std::move(memb));
-
- str.members.emplace_back(std::move(memb));
- }
- {
- c_types::c_member memb;
- }
-
-
- str.type = "struct ";
- str.type += type_str;
-
- str.type += " {\n";
-
- str.type += "\t" + inner_type_str + "* data;\n";
- str.type += "\tsize_t size;\n";
- if( Dim > 1 ){
- str.type += "\tsize_t dims["+std::to_string(Dim)+"];\n";
- }
-
- str.type += "};\n";
-
- c_state.struct_map.emplace(std::make_pair(type_str, std::move(str)));
- return void_t{};
- }
-};
-
-template<typename Interface>
-struct c_iface_translater {
- static_assert(always_false<Interface>,"Not supported");
-};
-
-template<class... Request, class Response, string_literal... Lits>
-struct c_iface_translater<schema::Function<schema::Struct<schema::Member<Request, Lits>...>, Response>> {
- using StructMap = typename c_types::c_struct_map;
- using FuncMap = typename c_types::c_func_map;
-
- template<size_t i>
- static error_or<void> generate_request_member(c_types::state& c_state, std::array<std::string, sizeof...(Request)>& type_arr){
- using Type = typename parameter_pack_type<i, Request...>::type;
- // constexpr string_literal lit = parameter_key_pack_type<i, Lits...>::literal;
-
- auto eov = c_data_translater<Type>::generate(c_state, type_arr.at(i));
- if(eov.is_error()){
- return eov;
- }
-
- if constexpr ((i+1) < sizeof...(Request)){
- auto eov = generate_request_member<i+1>(c_state, type_arr);
- return eov;
- }
-
- return void_t{};
- }
-
- template<size_t i>
- static error_or<void> generate_parameter(std::string& param_use, const std::array<std::string, sizeof...(Request)>& req_type_arr){
- using Type = typename parameter_pack_type<i, Request...>::type;
- constexpr string_literal lit = parameter_key_pack_type<i, Lits...>::literal;
-
- std::string used_param;
- if constexpr (c_is_primitive<Type>::value){
- used_param += req_type_arr.at(i);
- } else {
- used_param += "const " + req_type_arr.at(i) + "*";
- }
- param_use += used_param + " " + std::string{lit.view()};
-
- if constexpr ( (i+1) < sizeof...(Request) ){
- param_use += ", ";
- return generate_parameter<i+1>(param_use, req_type_arr);
- }
-
- return void_t{};
- }
-
- static error_or<void> generate(c_types::state& c_state, const std::string& func_name){
- std::array<std::string, sizeof...(Request)> request_type_arr;
-
- if constexpr (sizeof...(Request) > 0){
- auto eov = generate_request_member<0>(c_state, request_type_arr);
- if(eov.is_error()){
- return eov;
- }
- }
- std::string response_type_str;
- {
- auto eov = c_data_translater<Response>::generate(c_state, response_type_str);
- if(eov.is_error()){
- return eov;
- }
- }
-
- c_types::c_func fn;
- fn.cpp_name = func_name;
-
-
- c_state.func_map.emplace(std::make_pair(fn.cpp_name, std::move(fn)));
-
- return void_t{};
- }
-};
-
-template<class... Requests, class... Responses, string_literal... Names>
-struct c_iface_translater<schema::Interface<schema::Member<schema::Function<Requests, Responses>, Names>...>> {
- using Schema = schema::Interface<schema::Member<schema::Function<Requests, Responses>, Names>...>;
-
- template<size_t i>
- static error_or<void> generate_member(c_types::state& c_state){
- using Req = typename parameter_pack_type<i,Requests...>::type;
- using Resp = typename parameter_pack_type<i,Responses...>::type;
- constexpr string_literal lit = parameter_key_pack_type<i, Names...>::literal;
-
- try{
- std::stringstream iss;
- schema_stringify<Schema>::apply(iss);
- c_state.interface_schema = iss.str();
- }catch(const std::exception& e){
- (void) e;
- return make_error<err::critical>();
- }
-
- std::string c_func_name = c_state.prefix + "_" + std::string{lit.view()};
- if(c_state.func_map.find(c_func_name) != c_state.func_map.end()){
- return make_error<err::already_exists>();
- }
-
- {
- std::string type_str;
- auto eov = c_iface_translater<schema::Function<Req, Resp>>::generate(c_state, std::string{lit.view()});
- if(eov.is_error()){
- return eov;
- }
- }
-
- if constexpr ((i+1) < sizeof...(Requests) ){
- return generate_member<i+1>(c_state);
- }
- return void_t{};
- }
-
- static error_or<void> generate(c_types::state& c_state){
- if constexpr ( sizeof...(Requests) > 0 ){
- return generate_member<0>(c_state);
- }
-
- return void_t{};
- }
-};
-}
-
-template<typename Interface>
-error_or<void> generate_c_interface(typename impl::c_types::state& state){
- auto eov = impl::c_iface_translater<Interface>::generate(state);
- return eov;
-}
-
-error_or<void> generate_iface_example(){
- using Request1 = schema::Struct<
- schema::Member<schema::Int32, "foo">,
- schema::Member<schema::Float64, "bar">,
- schema::Member<schema::Array<schema::Float32,1>, "baz">
- >;
- using Response1 = schema::Int32;
-
- using Func1 = schema::Function<Request1, Response1>;
-
- using Iface = schema::Interface<
- schema::Member<Func1, "func_one">
- >;
-
- using CIfaceDesc = schema::Struct<
- Member<schema::String, "prefix">,
- Member<schema::String, "encoding">
- >;
-
- impl::c_types::state c_state;
- c_state.prefix = "c_saw";
- c_state.encoding = "saw::encode::Native";
-
- typename impl::c_types::c_struct_map& type_map = c_state.struct_map;
- typename impl::c_types::c_func_map& func_map = c_state.func_map;
- auto eov = generate_c_interface<Iface>(c_state);
- if(eov.is_error()){
- return eov;
- }
- std::cout<<"Interface: "<<c_state.interface_schema<<std::endl;
- std::cout<<"Prefix: "<<c_state.prefix<<std::endl;
- std::cout<<"\nTypes: "<<std::endl;
-
- for(auto& iter : type_map){
- std::cout<<"\nType: \""<<iter.first<<"\""<<std::endl;
- std::cout<<"Definition:\n\"\"\"\n";
- std::cout<<iter.second.type;
- std::cout<<"\"\"\""<<std::endl;
- std::cout<<"Schema: "<<iter.second.cpp_schema<<std::endl;
- }
- std::cout<<"\nFunctions: "<<std::endl;
-
- for(auto& iter : func_map){
- std::cout<<"\nSymbol: \""<<iter.first<<"\""<<std::endl;
- std::cout<<"Definition:\n\"\"\"\n";
- std::cout<<iter.second.cpp_name<<";\n";
- }
-
- return eov;
-}
-
-error_or<void> generate_array_example(){
- using Schema1 = schema::Array<schema::Int32,2>;
-
- using Schema2 = schema::Array<schema::Float64,5>;
-
- using Schema3 = schema::Array<schema::UInt16,1>;
-
- std::string prefix = "c_saw";
- impl::c_types::state c_state;
- c_state.prefix = prefix;
- {
- std::string type_str;
- auto eov = impl::c_data_translater<Schema1>::generate(c_state, type_str);
- if(eov.is_error()){
- return eov;
- }
- }
- {
- std::string type_str;
- auto eov = impl::c_data_translater<Schema2>::generate(c_state, type_str);
- if(eov.is_error()){
- return eov;
- }
- }
- {
- std::string type_str;
- auto eov = impl::c_data_translater<Schema3>::generate(c_state, type_str);
- if(eov.is_error()){
- return eov;
- }
- }
-
- std::cout<<"Prefix: "<<c_state.prefix<<std::endl;
-
- for(auto& iter : c_state.struct_map){
- std::cout<<"\nType: \""<<iter.first<<"\""<<std::endl;
- std::cout<<"Definition:\n\"\"\"\n";
- std::cout<<iter.second.type;
- std::cout<<"\"\"\""<<std::endl;
- }
-
- return void_t{};
-}
-}