summaryrefslogtreecommitdiff
path: root/modules/tools
diff options
context:
space:
mode:
authorClaudius "keldu" Holeksa <mail@keldu.de>2024-03-18 16:45:15 +0100
committerClaudius "keldu" Holeksa <mail@keldu.de>2024-03-18 16:45:15 +0100
commit3be0c08510661cdca813cc5f1f471450c2ef3ce5 (patch)
treea14ebacc4c4397870862b5f9f1b145abe1a336e1 /modules/tools
parent0906dff296214bbff9f0e08a3bebc8c58758aa3f (diff)
tools: Generating C interface sources for primitives
Diffstat (limited to 'modules/tools')
-rw-r--r--modules/tools/c++/c_gen_iface.hpp290
1 files changed, 264 insertions, 26 deletions
diff --git a/modules/tools/c++/c_gen_iface.hpp b/modules/tools/c++/c_gen_iface.hpp
index 8eb0bca..7dc1197 100644
--- a/modules/tools/c++/c_gen_iface.hpp
+++ b/modules/tools/c++/c_gen_iface.hpp
@@ -158,6 +158,76 @@ struct lang_bind_helper {
template<typename T, uint64_t L>
struct lang_bind<schema::Primitive<T,L>, binding::SyncC> {
using Schema = schema::Primitive<T,L>;
+
+ static error_or<void> generate_c_to_cpp(buffer& src, const language_binding_config& cfg, language_binding_state& state, const std::string_view& cpp_name, const std::string_view& c_name ){
+ {
+ auto eov = lang_bind_helper::append_string(src, "\t");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(src, cpp_name);
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(src, ".set(*");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(src, c_name);
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(src, ");\n");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ return void_t{};
+ }
+
+ static error_or<void> generate_cpp_to_c(buffer& src, const language_binding_config& cfg, language_binding_state& state, const std::string_view& cpp_name, const std::string_view& c_name ){
+
+ {
+ auto eov = lang_bind_helper::append_string(src, "\t*");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(src, c_name);
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(src, " = ");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(src, cpp_name);
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(src, ".get();\n");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+
+ return void_t{};
+ }
static error_or<void> generate(buffer& buff, buffer& src, const language_binding_config& cfg, language_binding_state& state){
constexpr uint64_t hash = schema_hash<Schema>::apply();
@@ -209,6 +279,14 @@ struct lang_bind<schema::Array<T,D>, binding::SyncC> {
static_assert(is_primitive<T>::value, "Currently only primitive type arrays are supported");
+ static error_or<void> generate_c_to_cpp(buffer& src, const language_binding_config& cfg, language_binding_state& state, const std::string_view& cpp_name, const std::string_view& c_name ){
+ return make_error<err::not_implemented>();
+ }
+
+ static error_or<void> generate_cpp_to_c(buffer& src, const language_binding_config& cfg, language_binding_state& state, const std::string_view& c_name, const std::string_view& cpp_name ){
+ return make_error<err::not_implemented>();
+ }
+
static error_or<void> generate(buffer& buff, buffer& src, const language_binding_config& cfg, language_binding_state& state){
constexpr uint64_t hash = schema_hash<Schema>::apply();
@@ -381,70 +459,144 @@ struct lang_bind<schema::Function<Input, Output>, binding::SyncC> {
constexpr uint64_t output_hash = schema_hash<Output>::apply();
/**
- * Function generations
+ * Source
*/
{
- auto eov = lang_bind<Input, binding::SyncC>::generate(buff, src, cfg, state);
- if(eov.is_error()){
- return eov;
- }
+ auto eov = append_function_def(src, cfg, state, f_name);
+ if(eov.is_error()){
+ return eov;
+ }
}
{
- auto eov = lang_bind<Output, binding::SyncC>::generate(buff, src, cfg, state);
- if(eov.is_error()){
- return eov;
+ auto eov = lang_bind_helper::append_string(src, "{\n\tif(!ctx || !(ctx->ctx)) return -1;\n\tif(!input) return -1;\n\tif(!output) return -1;\n");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(src, "\n\tauto& iface = ");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(src, cfg.prefix);
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(src, "_get_cpp_interface_priv(*ctx);\n\t");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ /**
+ * Check declarations and definitions.
+ * Translate input.
+ */
+ {
+ auto eov = lang_bind_helper::append_string(src, "saw::data<");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ std::stringstream ss;
+ try{
+ {
+ schema_stringify<Input>::apply(ss);
+ auto eov = lang_bind_helper::append_string(src, ss.str());
+ if(eov.is_error()){
+ return eov;
+ }
}
+ }catch(const std::exception&){
+ return make_error<err::out_of_memory>();
+ }
}
{
- auto eov = lang_bind_helper::append_string(buff, "typedef ");
+ auto eov = lang_bind_helper::append_string(src, "> cpp_input_root;\n");
if(eov.is_error()){
return eov;
}
}
{
- auto eov = lang_bind_helper::append_hashed_type(buff, cfg.prefix, schema_hash<Input>::apply());
+ auto eov = lang_bind<Input, binding::SyncC>::generate(buff, src, cfg, state);
if(eov.is_error()){
return eov;
}
}
{
- auto eov = lang_bind_helper::append_string(buff, " ");
+ auto eov = lang_bind<Input, binding::SyncC>::generate_c_to_cpp(src, cfg, state, "c_input_root", "cpp_input_root");
if(eov.is_error()){
return eov;
}
}
+ /**
+ * Call the c++ implementation
+ */
{
- auto eov = lang_bind_helper::append_string(buff, cfg.prefix);
+ auto eov = lang_bind_helper::append_string(src, "\n\tauto eov = iface.template call<\"");
if(eov.is_error()){
return eov;
}
}
{
- auto eov = lang_bind_helper::append_string(buff, "_");
+ auto eov = lang_bind_helper::append_string(src, f_name);
if(eov.is_error()){
return eov;
}
}
{
- auto eov = lang_bind_helper::append_string(buff, f_name);
+ auto eov = lang_bind_helper::append_string(src, "\">(std::move(cpp_input_root));\n");
if(eov.is_error()){
return eov;
}
}
{
- auto eov = lang_bind_helper::append_string(buff, "_input_t;\n");
+ auto eov = lang_bind_helper::append_string(src, "\tif(eov.is_error()){\n\t\tauto& err = eov.get_error();\n\t\treturn err.get_code();\n\t}\n\tauto& cpp_output_root = eov.get_value();\n\n");
if(eov.is_error()){
return eov;
}
}
{
+ auto eov = lang_bind<Input, binding::SyncC>::generate_cpp_to_c(src, cfg, state, "cpp_output_root", "c_output_root");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+
+ /**
+ * Check declarations and definitions.
+ * Translate output.
+ */
+ {
+ auto eov = lang_bind<Output, binding::SyncC>::generate(buff, src, cfg, state);
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ /**
+ * End source declaration
+ */
+ {
+ auto eov = lang_bind_helper::append_string(src, "\treturn 0;\n}\n\n");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ /**
+ * Header
+ */
+ {
auto eov = lang_bind_helper::append_string(buff, "typedef ");
if(eov.is_error()){
return eov;
}
}
{
- auto eov = lang_bind_helper::append_hashed_type(buff, cfg.prefix, schema_hash<Output>::apply());
+ auto eov = lang_bind_helper::append_hashed_type(buff, cfg.prefix, schema_hash<Input>::apply());
if(eov.is_error()){
return eov;
}
@@ -474,46 +626,64 @@ struct lang_bind<schema::Function<Input, Output>, binding::SyncC> {
}
}
{
- auto eov = lang_bind_helper::append_string(buff, "_output_t;\n");
+ auto eov = lang_bind_helper::append_string(buff, "_input_t;\n");
if(eov.is_error()){
return eov;
}
}
{
- auto eov = append_function_def(buff, cfg, state, f_name);
+ auto eov = lang_bind_helper::append_string(buff, "typedef ");
if(eov.is_error()){
return eov;
}
}
{
- auto eov = lang_bind_helper::append_string(buff, ";\n\n");
+ auto eov = lang_bind_helper::append_hashed_type(buff, cfg.prefix, schema_hash<Output>::apply());
if(eov.is_error()){
return eov;
}
}
- /**
- * Source
- */
{
- auto eov = append_function_def(src, cfg, state, f_name);
+ auto eov = lang_bind_helper::append_string(buff, " ");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(buff, cfg.prefix);
if(eov.is_error()){
return eov;
}
}
{
- auto eov = lang_bind_helper::append_string(src, "{\n\tif(!ctx) return -1;\n\tif(!input) return -1;\n\tif(!output) return -1;\n\t");
+ auto eov = lang_bind_helper::append_string(buff, "_");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(buff, f_name);
if(eov.is_error()){
return eov;
}
}
{
- auto eov = lang_bind_helper::append_string(src, "");
+ auto eov = lang_bind_helper::append_string(buff, "_output_t;\n");
if(eov.is_error()){
return eov;
}
}
+ /**
+ * Function generations
+ */
{
- auto eov = lang_bind_helper::append_string(src, "return 0;\n}\n\n");
+ auto eov = append_function_def(buff, cfg, state, f_name);
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(buff, ";\n\n");
if(eov.is_error()){
return eov;
}
@@ -554,6 +724,40 @@ struct lang_bind<schema::Interface<M...>, binding::SyncC> {
* Setup context creation to bind interface to a context
*/
/**
+ * Interface type helper
+ */
+ {
+ auto eov = lang_bind_helper::append_string(src, "namespace {\nnamespace schema {\n");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(src, "using InterfaceType = ");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ std::stringstream ss;
+ schema_stringify<schema::Interface<M...>>::apply(ss);
+ try {
+ auto eov = lang_bind_helper::append_string(src, ss.str());
+ if(eov.is_error()){
+ return eov;
+ }
+ }catch(const std::exception&){
+ return make_error<err::out_of_memory>("No memory after stringification");
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(src, ";\n}\n}\n\n");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+
+ /**
* Context definition
*/
/// @todo Add Macro which reduces typing time ? Not really that much shorter :/
@@ -639,6 +843,40 @@ struct lang_bind<schema::Interface<M...>, binding::SyncC> {
}
}
+ /**
+ * Create a casting helper in sources for the interface type
+ */
+ {
+ auto eov = lang_bind_helper::append_string(src, "saw::interface<>& ");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(src, cfg.prefix);
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(src, "_get_cpp_interface_priv(");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(src, cfg.prefix);
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(src, "& ctx){\n\treturn *reinterpret_cast<saw::interface<schema::InterfaceType>*>(ctx.ctx);\n}\n\n");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+
if constexpr (sizeof...(M) > 0){
return generate_element<0>(buff, src, cfg, state);
}