forked from enlightenment/efl
128 lines
4.9 KiB
C++
128 lines
4.9 KiB
C++
#ifndef EOLIAN_CXX_TYPE_FUNCTION_DECLARATION_HH
|
|
#define EOLIAN_CXX_TYPE_FUNCTION_DECLARATION_HH
|
|
|
|
#include "grammar/generator.hpp"
|
|
#include "grammar/klass_def.hpp"
|
|
|
|
#include "grammar/string.hpp"
|
|
#include "grammar/indentation.hpp"
|
|
#include "grammar/list.hpp"
|
|
#include "grammar/alternative.hpp"
|
|
#include "grammar/type.hpp"
|
|
#include "grammar/parameter.hpp"
|
|
#include "grammar/keyword.hpp"
|
|
#include "grammar/converting_argument.hpp"
|
|
#include "grammar/eps.hpp"
|
|
|
|
namespace efl { namespace eolian { namespace grammar {
|
|
|
|
/** This generates the caller struct for function pointers. */
|
|
struct type_function_declaration_generator {
|
|
type_function_declaration_generator() {}
|
|
|
|
template <typename OutputIterator, typename Context>
|
|
bool generate(OutputIterator sink, attributes::function_def const& f, Context const& ctx) const
|
|
{
|
|
std::string guard = f.c_name + "_defined";
|
|
|
|
if (!as_generator("#ifndef " << string << "\n" <<
|
|
"#define " << string << "\n")
|
|
.generate(sink, std::make_tuple(guard, guard), add_upper_case_context(ctx)))
|
|
return false;
|
|
|
|
// efl::eolian::function_wrapper<T, F>
|
|
if (!as_generator("namespace efl { namespace eolian {\n")
|
|
.generate(sink, attributes::unused, add_lower_case_context(ctx)))
|
|
return false;
|
|
|
|
if (!as_generator(
|
|
"template <typename F>\n"
|
|
"struct function_wrapper<" << string << ", F, struct " << string << "__function_tag> {\n"
|
|
<< scope_tab << "function_wrapper(F cxx_func) : _cxx_func(cxx_func) {}\n"
|
|
).generate(sink, std::make_tuple(f.c_name, f.c_name), ctx))
|
|
return false;
|
|
|
|
if (!as_generator(
|
|
scope_tab << "void *data_to_c() { return static_cast<void *>(this); }\n"
|
|
<< scope_tab << string << " func_to_c() const { return &caller; }\n"
|
|
<< scope_tab << "Eina_Free_Cb free_to_c() const { return &deleter; }\n"
|
|
<< "private:\n"
|
|
<< scope_tab << "F _cxx_func;\n"
|
|
<< scope_tab << "static void deleter(void *data) {\n"
|
|
<< scope_tab << scope_tab << "delete static_cast<function_wrapper<" << string << ", F, ::efl::eolian::" << string << "__function_tag>*>(data);\n"
|
|
<< scope_tab << "}\n"
|
|
).generate(sink, std::make_tuple(f.c_name, f.c_name, f.c_name), ctx))
|
|
return false;
|
|
|
|
std::vector<std::string> c_args;
|
|
for (auto itr : f.parameters)
|
|
{
|
|
std::string arg;
|
|
if (!as_generator(grammar::c_type << " " << string).generate(std::back_inserter(arg), std::make_tuple(itr, itr.param_name), ctx))
|
|
return false;
|
|
c_args.push_back(arg);
|
|
}
|
|
if (!as_generator(
|
|
scope_tab << "static " << string << " caller(void *cxx_call_data"
|
|
<< *(", " << string) << ") {\n"
|
|
<< scope_tab << scope_tab << "auto fw = static_cast<function_wrapper<"
|
|
<< string << ", F, ::efl::eolian::" << string << "__function_tag>*>(cxx_call_data);\n"
|
|
).generate(sink, std::make_tuple(f.return_type.c_type, c_args, f.c_name, f.c_name), ctx))
|
|
return false;
|
|
|
|
if (f.return_type != attributes::void_
|
|
&& !as_generator(scope_tab << scope_tab << "auto __return_value =\n")
|
|
.generate(sink, attributes::unused, ctx))
|
|
return false;
|
|
|
|
if (!f.parameters.empty())
|
|
{
|
|
std::vector<attributes::parameter_def> params;
|
|
for (auto itr = f.parameters.begin() + 1; itr != f.parameters.end(); itr++)
|
|
params.push_back(*itr);
|
|
if (!as_generator(
|
|
scope_tab << scope_tab << "fw->_cxx_func(" << parameter_as_argument << *(", " << parameter_as_argument) << ");\n"
|
|
).generate(sink, std::make_tuple(*f.parameters.begin(), params), ctx))
|
|
return false;
|
|
}
|
|
|
|
if (f.return_type != attributes::void_
|
|
&& !as_generator(scope_tab << scope_tab << "return ::efl::eolian::convert_to_c<"
|
|
<< type << ">(__return_value);\n")
|
|
.generate(sink, f.return_type, ctx))
|
|
return false;
|
|
|
|
if (!as_generator(scope_tab << "}\n").generate(sink, attributes::unused, ctx))
|
|
return false;
|
|
|
|
if (!as_generator("};\n"
|
|
"} }\n"
|
|
"#endif\n\n")
|
|
.generate(sink, attributes::unused, ctx))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct is_eager_generator<type_function_declaration_generator> : std::true_type {};
|
|
template <>
|
|
struct is_generator<type_function_declaration_generator> : std::true_type {};
|
|
namespace type_traits {
|
|
template <>
|
|
struct attributes_needed<type_function_declaration_generator> : std::integral_constant<int, 1> {};
|
|
}
|
|
|
|
struct type_function_declaration_terminal
|
|
{
|
|
type_function_declaration_generator operator()() const
|
|
{
|
|
return type_function_declaration_generator{};
|
|
}
|
|
} const type_function_declaration = {};
|
|
|
|
} } }
|
|
|
|
#endif
|