efl/src/lib/eolian_cxx/grammar/eo_class_functions_generato...

153 lines
3.8 KiB
C++

#ifndef EOLIAN_CXX_STD_EO_CLASS_FUNCTIONS_GENERATOR_HH
#define EOLIAN_CXX_STD_EO_CLASS_FUNCTIONS_GENERATOR_HH
#include <iosfwd>
#include "eo_types.hh"
#include "tab.hh"
#include "comment.hh"
#include "parameters_generator.hh"
#include "type_generator.hh"
#include "namespace_generator.hh"
#include "eo_class_scope_guard_generator.hh"
namespace efl { namespace eolian { namespace grammar {
struct function_call
{
eo_function const& _func;
function_call(eo_function const& func) : _func(func) {}
};
inline std::ostream&
operator<<(std::ostream& out, function_call const& x)
{
bool is_void = function_is_void(x._func);
return out << (!is_void ? "_tmp_ret = " : "")
<< "::" << x._func.impl
<< "(" << parameters_forward_to_c(x._func.params) << ")";
}
struct function_declaration
{
eo_class const& _cls;
eo_function const& _func;
function_declaration(eo_class const& cls, eo_function const& func)
: _cls(cls), _func(func)
{}
};
inline std::ostream&
operator<<(std::ostream& out, function_declaration const& x)
{
eo_function const& func = x._func;
out << comment(x._func.comment, 1)
<< template_parameters_declaration(func.params, 1)
<< tab(1);
bool is_static = function_is_static(func);
if (is_static)
out << "static ";
out << reinterpret_type(func.ret) << " " << func.name << "("
<< parameters_declaration(func.params)
<< (is_static ? ");" : ") const;") << endl;
return out;
}
struct function_definition
{
eo_class const& _cls;
eo_function const& _func;
bool _concrete;
function_definition(eo_class const& cls, eo_function const& func, bool concrete)
: _cls(cls), _func(func), _concrete(concrete)
{}
};
inline std::ostream&
operator<<(std::ostream& out, function_definition const& x)
{
eo_function const& func = x._func;
bool is_static = function_is_static(func);
out << template_parameters_declaration(func.params, 0)
<< "inline " << reinterpret_type(func.ret) << " ";
if (x._concrete)
out << full_name(x._cls, false);
else
out << abstract_full_name(x._cls, false);
out << "::" << func.name << "("
<< parameters_declaration(func.params)
<< (is_static ? ")" : ") const") << endl
<< "{" << endl;
if (!function_is_void(func))
out << tab(1)
<< func.ret.front().native << " _tmp_ret;" << endl;
out << callbacks_heap_alloc("_concrete_eo_ptr()", func.params, is_static, 1);
out << tab(1) << "eo_do("
<< (is_static ? "_eo_class(), " : "_concrete_eo_ptr(), ")
<< function_call(x._func) << ");" << endl;
if (!function_is_void(func))
out << tab(1) << "return " << to_cxx(func.ret, "_tmp_ret") << ";" << endl;
out << "}" << endl;
return out;
}
struct function_declarations
{
eo_class const& _cls;
function_declarations(eo_class const& cls)
: _cls(cls)
{}
};
inline std::ostream&
operator<<(std::ostream& out, function_declarations const& x)
{
for (eo_function const& f : x._cls.functions)
{
out << scope_guard_head(x._cls, f)
<< function_declaration(x._cls, f)
<< scope_guard_tail(x._cls, f) << endl;
}
return out;
}
struct function_definitions
{
eo_class const& _cls;
bool _concrete;
function_definitions(eo_class const& cls, bool concrete)
: _cls(cls)
, _concrete(concrete)
{}
};
inline std::ostream&
operator<<(std::ostream& out, function_definitions const& x)
{
for (eo_function const& f : x._cls.functions)
{
out << scope_guard_head(x._cls, f)
<< function_definition(x._cls, f, x._concrete)
<< scope_guard_tail(x._cls, f) << endl;
}
return out;
}
} } } // namespace efl { namespace eolian { namespace grammar {
#endif // EOLIAN_CXX_STD_EO_CLASS_FUNCTIONS_GENERATOR_HH