diff --git a/pEpACIDgen/gen_backend/gen_pybind11.ysl2 b/pEpACIDgen/gen_backend/gen_pybind11.ysl2 index 2643fc7..25729d7 100644 --- a/pEpACIDgen/gen_backend/gen_pybind11.ysl2 +++ b/pEpACIDgen/gen_backend/gen_pybind11.ysl2 @@ -4,40 +4,93 @@ tstylesheet { template "module" { document("py_module.pybind11", "text") { || + // INSERT COOL ASCII ART HERE + // METHOD `` apply "method" + + // STRUCTS `` apply "struct" + + // ENUMS `` apply "enum" || } } + function "method_2_signature_c" { + > «return[1]/@type» «@name»( + for "use" { + > «@type» «@name»`if "position()!=last()" > , ` + } + > ) + } + + template "method" { + const "signature_c" call "method_2_signature_c"; || + //«$signature_c» m.def("«@name»", - [](`apply "use", mode="lambda_sig"`) -> pybind11::tuple { - `apply "return", mode="create"` + [] + ( + ``apply "use", mode="arg_list_from_py" + ) -> pybind11::tuple + { + ``apply "return", mode="create" + ``apply "use", mode="create_args_c" `apply "return", mode="assign"`::«@name»( - ``apply "use", mode="arg_list" + ``apply "use", mode="arg_list_c" ); return pybind11::make_tuple( - ret`if "count(use)>0" > ,` - ``apply "use", mode="return_as_tuple" + `apply "return", mode="return"``if "count(use)>0" > ,` + ``apply "use", mode="return_args_as_tuple" ); }, pybind11::return_value_policy::copy); || } + + // Creates the dereferences for given pointer type, to create + // the simple pointer type of it. (char*) + // char*** => ** + function "dereference" { + param "type"; + const "type_pointers_minus1", "substring-after($type,'*')"; + > «$type_pointers_minus1» + } + + template "return" mode="return" { + const "type", "@type"; + choose { + when "contains($type,'void')" { + > pybind11::none() + } otherwise { + choose { + when "contains($type,'*')" { + choose { + when "contains($type,'char')" { + > std::string(`call "dereference" with "type", "$type"`ret) + } otherwise { + > `call "dereference" with "type", "$type"`*ret + } + } + } otherwise { + > ret + } + } + } + } + } + template "return" mode="create" { const "type", "@type"; choose { when "$type != 'void'" { - > «@type» ret; - } otherwise { - > pybind11::none ret; + | «@type» ret; } } } @@ -51,7 +104,23 @@ tstylesheet { } } - template "use", mode="return_as_tuple" { + template "use" mode="create_args_c" { + const "name", "@name"; + const "type", "@type"; + const "type_decayed" call "decay" with "type", "$type"; + const "pchain" call "dereference" with "type", "@type"; + const "pchain_tokenizable", "str:replace($pchain,'*','* ')"; + const "pchain_tokens", "str:tokenize($pchain_tokenizable, ' ')"; + + for "$pchain_tokens" { + const "pointers", "substring($pchain,0,position()+1)"; + const "pprefix", "str:replace($pointers,'*','p')"; + const "prev_prefix", "substring($pprefix,0,position())"; + | «$type_decayed»«$pointers» «$pprefix»«$name» = &«$prev_prefix»«$name»; + } + } + + template "use", mode="return_args_as_tuple" { const "name", "@name"; const "type", "@type"; choose { @@ -62,38 +131,52 @@ tstylesheet { } // TODO: UTTTTER PEP-SPECIFIC HACKS (PEP_SESSION) - template "use", mode="arg_list" { + template "use", mode="arg_list_c" { const "name", "@name"; const "type", "@type"; + const "type_deref" call "dereference" with "type", "$type"; + const "pprefix", "str:replace($type_deref, '*', 'p')"; choose { - when "$type = 'const char *'" { - |> strdup(«$name»)`if "position()!=last()" > ,` - } when "$type = 'PEP_SESSION'" { |> pep_session()`if "position()!=last()" > ,` } otherwise { - |> «$name»`if "position()!=last()" > ,` + |> «$pprefix»«$name»`if "position()!=last()" > ,` } } } - template "use", mode="lambda_sig" { + // Decays the type to basic value or pointer type + // int* => int* + // int** => int* + // int**** => int* + // int => int + function "decay" { + param "type"; + choose { + when "contains($type,'*')" { + > «substring-before($type,'*')»* + } otherwise { + > «$type» + } + } + } + + template "use", mode="arg_list_from_py" { const "name", "@name"; const "type", "@type"; choose { when "$type != 'PEP_SESSION'"{ - > «$type» «$name»`if "position()!=last()"> , ` + | `call "decay" with "type", "$type"` «$name»`if "position()!=last()"> , ` } } } -// template "signature" { -// const "string", "@string"; -// > «$string» -// } template "struct" { - | pybind11::class_<«@name»>(m, "«@name»") + || + pybind11::class_<«@name»>(m, "«@name»") + .def(pybind11::init([]() { return «@name»(); })) + || apply "field" { with "structname", "@name" }