forked from enlightenment/efl
cxx: Add support for function pointers
This was tested on the function pointer Efl.Ui.Format_Func_Cb
This commit is contained in:
parent
a597084db7
commit
5425baa906
|
@ -25,6 +25,7 @@
|
|||
#include "grammar/klass_def.hpp"
|
||||
#include "grammar/header.hpp"
|
||||
#include "grammar/impl_header.hpp"
|
||||
#include "grammar/types_definition.hpp"
|
||||
|
||||
namespace eolian_cxx {
|
||||
|
||||
|
@ -58,7 +59,8 @@ opts_check(eolian_cxx::options_type const& opts)
|
|||
}
|
||||
|
||||
static bool
|
||||
generate(const Eolian_Class* klass, eolian_cxx::options_type const& opts)
|
||||
generate(const Eolian_Class* klass, eolian_cxx::options_type const& opts,
|
||||
std::string const& cpp_types_header)
|
||||
{
|
||||
std::string header_decl_file_name = opts.out_file.empty()
|
||||
? (::eolian_class_file_get(klass) + std::string(".hh")) : opts.out_file;
|
||||
|
@ -153,12 +155,13 @@ generate(const Eolian_Class* klass, eolian_cxx::options_type const& opts)
|
|||
, efl::eolian::grammar::context_null{});
|
||||
|
||||
std::tuple<std::string, std::set<std::string>&, std::set<std::string>&
|
||||
, std::string const&
|
||||
, std::vector<efl::eolian::grammar::attributes::klass_def>&
|
||||
, std::vector<efl::eolian::grammar::attributes::klass_def>&
|
||||
, std::vector<efl::eolian::grammar::attributes::klass_def>&
|
||||
, std::vector<efl::eolian::grammar::attributes::klass_def>&
|
||||
> attributes
|
||||
{guard_name, c_headers, cpp_headers, klasses, forward_klasses, klasses, klasses};
|
||||
{guard_name, c_headers, cpp_headers, cpp_types_header, klasses, forward_klasses, klasses, klasses};
|
||||
|
||||
if(opts.out_file == "-")
|
||||
{
|
||||
|
@ -205,19 +208,117 @@ generate(const Eolian_Class* klass, eolian_cxx::options_type const& opts)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
types_generate(std::string const& fname, options_type const& opts,
|
||||
std::string& cpp_types_header)
|
||||
{
|
||||
using namespace efl::eolian::grammar::attributes;
|
||||
|
||||
std::vector<function_def> functions;
|
||||
Eina_Iterator *itr = eolian_declarations_get_by_file(fname.c_str());
|
||||
/* const */ Eolian_Declaration *decl;
|
||||
|
||||
// Build list of functions with their parameters
|
||||
while(::eina_iterator_next(itr, reinterpret_cast<void**>(&decl)))
|
||||
{
|
||||
Eolian_Declaration_Type dt = eolian_declaration_type_get(decl);
|
||||
if (dt != EOLIAN_DECL_ALIAS)
|
||||
continue;
|
||||
|
||||
const Eolian_Typedecl *tp = eolian_declaration_data_type_get(decl);
|
||||
if (!tp || eolian_typedecl_is_extern(tp))
|
||||
continue;
|
||||
|
||||
if (::eolian_typedecl_type_get(tp) != EOLIAN_TYPEDECL_FUNCTION_POINTER)
|
||||
continue;
|
||||
|
||||
const Eolian_Function *func = eolian_typedecl_function_pointer_get(tp);
|
||||
if (!func) return false;
|
||||
|
||||
Eina_Iterator *param_itr = eolian_function_parameters_get(func);
|
||||
std::vector<parameter_def> params;
|
||||
|
||||
/* const */ Eolian_Function_Parameter *param;
|
||||
while (::eina_iterator_next(param_itr, reinterpret_cast<void **>(¶m)))
|
||||
{
|
||||
parameter_direction param_dir;
|
||||
switch (eolian_parameter_direction_get(param))
|
||||
{
|
||||
/* Note: Inverted on purpose, as the direction objects are
|
||||
* passed is inverted (from C to C++ for function pointers).
|
||||
* FIXME: This is probably not right in all cases. */
|
||||
case EOLIAN_IN_PARAM: param_dir = parameter_direction::out; break;
|
||||
case EOLIAN_INOUT_PARAM: param_dir = parameter_direction::inout; break;
|
||||
case EOLIAN_OUT_PARAM: param_dir = parameter_direction::in; break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
const Eolian_Type *param_type_eolian = eolian_parameter_type_get(param);
|
||||
type_def param_type(param_type_eolian, opts.unit, EOLIAN_C_TYPE_PARAM);
|
||||
std::string param_name = eolian_parameter_name_get(param);
|
||||
std::string param_c_type = eolian_type_c_type_get(param_type_eolian, EOLIAN_C_TYPE_PARAM);
|
||||
parameter_def param_def(param_dir, param_type, param_name, param_c_type);
|
||||
params.push_back(std::move(param_def));
|
||||
}
|
||||
::eina_iterator_free(param_itr);
|
||||
|
||||
const Eolian_Type *ret_type_eolian = eolian_function_return_type_get(func, EOLIAN_FUNCTION_POINTER);
|
||||
|
||||
type_def ret_type = void_;
|
||||
if (ret_type_eolian)
|
||||
ret_type = type_def(ret_type_eolian, opts.unit, EOLIAN_C_TYPE_RETURN);
|
||||
|
||||
/*
|
||||
// List namespaces. Not used as function_wrapper lives in efl::eolian.
|
||||
std::vector<std::string> namespaces;
|
||||
Eina_Iterator *ns_itr = eolian_typedecl_namespaces_get(tp);
|
||||
char *ns;
|
||||
while (::eina_iterator_next(ns_itr, reinterpret_cast<void**>(&ns)))
|
||||
namespaces.push_back(std::string(ns));
|
||||
::eina_iterator_free(ns_itr);
|
||||
*/
|
||||
|
||||
std::string name = eolian_function_name_get(func);
|
||||
std::string c_name = eolian_typedecl_full_name_get(tp);
|
||||
std::replace(c_name.begin(), c_name.end(), '.', '_');
|
||||
bool beta = eolian_function_is_beta(func);
|
||||
|
||||
function_def def(ret_type, name, params, c_name, beta, false, true);
|
||||
functions.push_back(std::move(def));
|
||||
}
|
||||
::eina_iterator_free(itr);
|
||||
|
||||
if (functions.empty())
|
||||
return true;
|
||||
|
||||
std::stringstream sink;
|
||||
|
||||
sink.write("\n", 1);
|
||||
if (!efl::eolian::grammar::types_definition
|
||||
.generate(std::ostream_iterator<char>(sink),
|
||||
functions, efl::eolian::grammar::context_null()))
|
||||
return false;
|
||||
|
||||
cpp_types_header = sink.str();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
run(options_type const& opts)
|
||||
{
|
||||
if(!opts.main_header)
|
||||
{
|
||||
const Eolian_Class *klass = NULL;
|
||||
const Eolian_Class *klass = nullptr;
|
||||
char* dup = strdup(opts.in_files[0].c_str());
|
||||
char* base = basename(dup);
|
||||
klass = ::eolian_class_get_by_file(NULL, base);
|
||||
std::string cpp_types_header;
|
||||
klass = ::eolian_class_get_by_file(nullptr, base);
|
||||
free(dup);
|
||||
if (klass)
|
||||
{
|
||||
if (!generate(klass, opts))
|
||||
if (!types_generate(base, opts, cpp_types_header) ||
|
||||
!generate(klass, opts, cpp_types_header))
|
||||
{
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Error generating: " << ::eolian_class_name_get(klass)
|
||||
|
|
|
@ -61,6 +61,8 @@ template <>
|
|||
struct out_traits<void*> { typedef void*& type; };
|
||||
template <typename T>
|
||||
struct out_traits<efl::shared_future<T>> { typedef efl::shared_future<T>& type; };
|
||||
template <>
|
||||
struct out_traits<efl::eina::strbuf> { typedef efl::eina::strbuf_wrapper& type; };
|
||||
|
||||
template <typename T>
|
||||
struct inout_traits { typedef T& type; };
|
||||
|
@ -291,23 +293,7 @@ auto convert_inout(V& object) -> decltype(impl::convert_inout_impl(object, impl:
|
|||
template <typename T, typename U, bool Own = false, typename V>
|
||||
T convert_to_c(V&& object);
|
||||
|
||||
template <typename F, typename T>
|
||||
void* data_function_ptr_to_c(T)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename F, typename T>
|
||||
F function_ptr_to_c()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename F, typename T>
|
||||
Eina_Free_Cb free_function_ptr_to_c()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
template <typename U, typename F, typename V=void> struct function_wrapper;
|
||||
|
||||
namespace impl {
|
||||
|
||||
|
|
|
@ -33,24 +33,12 @@ struct converting_argument_generator
|
|||
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& ctx) const
|
||||
{
|
||||
attributes::qualifier_def qualifier = param.type.original_type.visit(attributes::get_qualifier_visitor{});
|
||||
bool is_function_ptr = param.type.original_type.visit(this->is_function_ptr);
|
||||
if(is_function_ptr)
|
||||
return as_generator
|
||||
(
|
||||
attribute_reorder<-1, -1, 2, -1, -1, -1, -1>
|
||||
(
|
||||
" ::efl::eolian::data_function_ptr_to_c<" << c_type
|
||||
<< ", " << parameter_type
|
||||
<< ">(" << string << ")"
|
||||
|
||||
", ::efl::eolian::function_ptr_to_c<" << c_type
|
||||
<< ", " << parameter_type
|
||||
<< ">()"
|
||||
", ::efl::eolian::free_function_ptr_to_c<" << c_type
|
||||
<< ", " << parameter_type
|
||||
<< ">()"
|
||||
)
|
||||
).generate(sink, param, ctx);
|
||||
if (param.type.original_type.visit(this->is_function_ptr))
|
||||
{
|
||||
// FIXME: This supports only one function pointer.
|
||||
return as_generator("fw->data_to_c(), fw->func_to_c(), fw->free_to_c()")
|
||||
.generate(sink, param, ctx);
|
||||
}
|
||||
else
|
||||
return as_generator
|
||||
(
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_FUNCTION_DECLARATION_HH
|
||||
#define EOLIAN_CXX_FUNCTION_DECLARATION_HH
|
||||
|
||||
|
@ -42,6 +43,13 @@ struct function_declaration_generator
|
|||
!as_generator("#ifdef " << *(string << "_") << string << "_" << string << "_BETA\n")
|
||||
.generate(sink, std::make_tuple(_klass_name.namespaces, _klass_name.eolian_name, suffix), add_upper_case_context(ctx)))
|
||||
return false;
|
||||
|
||||
std::string template_statement(f.template_statement());
|
||||
if (!template_statement.empty() &&
|
||||
!as_generator(template_statement << " ")
|
||||
.generate(sink, attributes::unused, ctx))
|
||||
return false;
|
||||
|
||||
if(!as_generator
|
||||
("::efl::eolian::return_traits<" << grammar::type(true) << ">::type " << string << "(" << (parameter % ", ") << ") const;\n")
|
||||
.generate(sink, std::make_tuple(f.return_type, escape_keyword(f.name), f.parameters), ctx))
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "grammar/attribute_conditional.hpp"
|
||||
#include "grammar/attribute_reorder.hpp"
|
||||
#include "grammar/type_impl.hpp"
|
||||
#include "grammar/eps.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
|
@ -53,11 +54,23 @@ struct function_definition_generator
|
|||
.generate(sink, std::make_tuple(_klass_name.namespaces, _klass_name.eolian_name), add_upper_case_context(ctx)))
|
||||
return false;
|
||||
|
||||
std::string template_statement(f.template_statement());
|
||||
if (!template_statement.empty() &&
|
||||
!as_generator(template_statement << "\n")
|
||||
.generate(sink, attributes::unused, ctx))
|
||||
return false;
|
||||
|
||||
if(!as_generator
|
||||
("inline ::efl::eolian::return_traits<" << grammar::type(true) << ">::type " << string << "::" << string << "(" << (parameter % ", ") << ") const\n{\n")
|
||||
.generate(sink, std::make_tuple(f.return_type, _klass_name.eolian_name, escape_keyword(f.name), f.parameters), ctx))
|
||||
return false;
|
||||
|
||||
std::vector<std::string> opening_statements(f.opening_statements());
|
||||
if (!opening_statements.empty() &&
|
||||
!as_generator(scope_tab << *(string) << "\n")
|
||||
.generate(sink, std::make_tuple(opening_statements), ctx))
|
||||
return false;
|
||||
|
||||
auto out_declaration =
|
||||
attribute_conditional([] (attributes::parameter_def const& p) -> bool
|
||||
{ return p.direction == attributes::parameter_direction::out; })
|
||||
|
@ -118,8 +131,8 @@ struct function_definition_generator
|
|||
scope_tab << "::efl::eolian::assign_out<" << parameter_type << ", " << c_type
|
||||
<<
|
||||
(
|
||||
attribute_conditional([] (attributes::type_def const& type)
|
||||
{ return type.original_type.visit(attributes::get_qualifier_visitor{}) & qualifier_info::is_own; })
|
||||
attribute_conditional([] (attributes::type_def const& typ)
|
||||
{ return typ.original_type.visit(attributes::get_qualifier_visitor{}) & qualifier_info::is_own; })
|
||||
[
|
||||
", true"
|
||||
] | eps
|
||||
|
|
|
@ -24,6 +24,7 @@ auto class_header =
|
|||
<< "#include <Eina.hh>\n"
|
||||
"#include <Eo.hh>\n"
|
||||
<< *header_include_directive // sequence<string>
|
||||
<< string // extra header <string>
|
||||
<< *class_declaration // sequence<class> | class
|
||||
<< *class_forward_declaration // sequence<class> | class
|
||||
<< "\nnamespace eo_cxx {\n"
|
||||
|
|
|
@ -433,6 +433,7 @@ struct function_def
|
|||
std::string filename;
|
||||
bool is_beta;
|
||||
bool is_protected;
|
||||
bool is_function_pointer;
|
||||
|
||||
friend inline bool operator==(function_def const& lhs, function_def const& rhs)
|
||||
{
|
||||
|
@ -442,17 +443,27 @@ struct function_def
|
|||
&& lhs.c_name == rhs.c_name
|
||||
&& lhs.filename == rhs.filename
|
||||
&& lhs.is_beta == rhs.is_beta
|
||||
&& lhs.is_protected == rhs.is_protected;
|
||||
&& lhs.is_protected == rhs.is_protected
|
||||
&& lhs.is_function_pointer == rhs.is_function_pointer;
|
||||
}
|
||||
friend inline bool operator!=(function_def const& lhs, function_def const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
function_def() = default;
|
||||
function_def(type_def return_type, std::string name, std::vector<parameter_def> parameters
|
||||
, std::string c_name, std::string filename, bool is_beta)
|
||||
: return_type(return_type), name(name), parameters(parameters), c_name(c_name), filename(filename), is_beta(is_beta) {}
|
||||
function_def() = default;
|
||||
function_def(type_def _return_type, std::string const& _name,
|
||||
std::vector<parameter_def> const& _parameters,
|
||||
std::string const& _c_name,
|
||||
bool _is_beta = false,
|
||||
bool _is_protected = false,
|
||||
bool _is_function_pointer = false)
|
||||
: return_type(_return_type), name(_name), parameters(_parameters),
|
||||
c_name(_c_name), is_beta(_is_beta), is_protected(_is_protected),
|
||||
is_function_pointer(_is_function_pointer) {}
|
||||
|
||||
function_def( ::Eolian_Function const* function, Eolian_Function_Type type, Eolian_Unit const* unit)
|
||||
: return_type(void_)
|
||||
{
|
||||
|
@ -517,6 +528,49 @@ struct function_def
|
|||
is_protected = eolian_function_scope_get(function, type) == EOLIAN_SCOPE_PROTECTED;
|
||||
is_protected = eolian_function_scope_get(function, type) == EOLIAN_SCOPE_PROTECTED;
|
||||
}
|
||||
|
||||
std::string template_statement() const
|
||||
{
|
||||
std::string statement;
|
||||
char template_typename = 'F';
|
||||
for (auto const& param : this->parameters)
|
||||
{
|
||||
attributes::regular_type_def const* typ =
|
||||
efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
|
||||
if (typ && typ->is_function_ptr)
|
||||
{
|
||||
char typenam[2] = { 0, };
|
||||
typenam[0] = template_typename++;
|
||||
if (statement.empty())
|
||||
statement = std::string("template <typename ") + typenam;
|
||||
else
|
||||
statement += std::string(", typename ") + typenam;
|
||||
}
|
||||
}
|
||||
if (statement.empty()) return statement;
|
||||
else return statement + ">";
|
||||
}
|
||||
|
||||
std::vector<std::string> opening_statements() const
|
||||
{
|
||||
// FIXME: Supports only one function pointer
|
||||
std::vector<std::string> statements;
|
||||
char template_typename = 'F';
|
||||
for (auto const& param : this->parameters)
|
||||
{
|
||||
attributes::regular_type_def const* typ =
|
||||
efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
|
||||
if (typ && typ->is_function_ptr)
|
||||
{
|
||||
char typenam[2] = { 0, };
|
||||
typenam[0] = template_typename++;
|
||||
std::string statement = "auto fw = new ::efl::eolian::function_wrapper<";
|
||||
statement += param.c_type + ", " + typenam + ">(" + param.param_name + ");";
|
||||
statements.push_back(statement);
|
||||
}
|
||||
}
|
||||
return statements;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
|
|
|
@ -25,6 +25,12 @@ struct parameter_type_generator
|
|||
dir = "in";
|
||||
break;
|
||||
}
|
||||
|
||||
attributes::regular_type_def const* typ =
|
||||
efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
|
||||
if (typ && typ->is_function_ptr)
|
||||
return as_generator("F").generate(sink, attributes::unused, context);
|
||||
|
||||
return as_generator
|
||||
(
|
||||
" ::efl::eolian::" << string << "_traits<"
|
||||
|
@ -44,6 +50,8 @@ struct attributes_needed<parameter_type_generator> : std::integral_constant<int,
|
|||
|
||||
parameter_type_generator const parameter_type = {};
|
||||
|
||||
|
||||
/* */
|
||||
struct parameter_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Context>
|
||||
|
@ -63,6 +71,25 @@ struct attributes_needed<parameter_generator> : std::integral_constant<int, 1> {
|
|||
}
|
||||
parameter_generator const parameter = {};
|
||||
|
||||
|
||||
/* */
|
||||
struct parameter_as_argument_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
|
||||
{
|
||||
return as_generator(parameter_type << "(" << string << ")").generate(sink, std::make_tuple(param, param.param_name), context);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<parameter_as_argument_generator> : std::true_type {};
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed<parameter_as_argument_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
parameter_as_argument_generator const parameter_as_argument = {};
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
#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> {\n"
|
||||
<< scope_tab << "function_wrapper(F cxx_func) : _cxx_func(cxx_func) {}\n"
|
||||
).generate(sink, 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>*>(data);\n"
|
||||
<< scope_tab << "}\n"
|
||||
).generate(sink, std::make_tuple(f.c_name, f.c_name), ctx))
|
||||
return false;
|
||||
|
||||
std::vector<std::string> c_args;
|
||||
for (auto itr : f.parameters)
|
||||
c_args.push_back(", " + itr.c_type + " " + itr.param_name);
|
||||
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>*>(cxx_call_data);\n"
|
||||
).generate(sink, std::make_tuple(f.return_type.c_type, c_args, 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 {};
|
||||
|
||||
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
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef EOLIAN_CXX_TYPES_DEFINITION_HH
|
||||
#define EOLIAN_CXX_TYPES_DEFINITION_HH
|
||||
|
||||
#include "header_guards.hpp"
|
||||
#include "eps.hpp"
|
||||
#include "string.hpp"
|
||||
#include "sequence.hpp"
|
||||
#include "kleene.hpp"
|
||||
#include "header_include_directive.hpp"
|
||||
#include "type_function_declaration.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct types_definition_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, std::vector<attributes::function_def> const& functions, Context const& ctx) const
|
||||
{
|
||||
if(!as_generator(*(type_function_declaration()))
|
||||
.generate(sink, functions, ctx))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<types_definition_generator> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed<types_definition_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
types_definition_generator const types_definition = {};
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue