Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Project status #8

Open
blockspacer opened this issue Oct 2, 2019 · 6 comments
Open

Project status #8

blockspacer opened this issue Oct 2, 2019 · 6 comments

Comments

@blockspacer
Copy link

blockspacer commented Oct 2, 2019

This project is very interesting.

Some of autoprogrammer's features in TODO status, so i wanted to add them.

I want to use some proposed features (like metaclasses) without waiting 3+ years for new C++ standard and can`t find stable (ready) solution.

Inspired by autoprogrammer's approach i created https://github.com/blockspacer/CXXCTP

Maybe some ideas from that project will be useful for autoprogrammer.

  • I found what jinja to C++ binding produced a lot of boilerplate code.
    I replaced jinja with https://github.com/blockspacer/CXTPL
    cxtpl uses approach similar to How to write a template engine in less than 30 lines of code from https://bits.theorem.co/how-to-write-a-template-library/
    That approach allowed to remove jinja2_reflector_generator.cpp completely

  • I can't find docs about autoprogrammer's C++ interpreter, so i used Cling as C++ interpreter. Maybe autoprogrammer's solution is less verbose or feature rich (i just can't understand it without some docs).

  • I wanted to add feature-complete Rust-like traits into C++. That's why i added to typeclasses generator typeclass combinations (when some typeclasses may be not set), std::ref support, typeclass merging (when all typeclasses must be set), out-of-source methods (so method may be defined in separate lib), typeclass with template parameters. Now typeclass instance accepts impl as first template argument, and all other template arguments may be used to combine typeclasses.

  • I wanted to chain multiple metaclasses, so i added custom C++ attribute syntax, very similar to calling C++ functions.


// $apply is just macro that adds attribute

class 
$apply(make_interface;make_removefuncbody;make_reflect)
SomeInterfaceName {
  virtual ~SomeInterfaceName() = 0;
  /*int    f   (   )   {     // {}
    int i = 6;
    {
      // {
      // }
    }
    return i;
  };*/
  int foo();
  virtual void foobar(int& arg1) = 0;
  virtual inline void zoobar(int& arg2);
  //int m_bar;
  //int m_bar2 = 2;
};

In attribute i can list needed metaclasses. Each metaclass is function (like make_interface) that returns modified source code or generated file.

  • I wanted to create tool not focused on predefined set of source transformation rules. That's why i added per-project ctp_scripts folder. If ctp_scripts used by separate project - all rules from ctp_scripts must be imported into Cling, so it behaves like interpreted plugin system. Because interpreted code runs slower - i added custom_plugins.cmake.example, so 'plugin' may be compiled and used as built-in tool plugin. Maybe it is better to create .dll/.so based plugin system.
@flexferrum
Copy link
Owner

flexferrum commented Oct 3, 2019

Thank you for interesting in the project. I'm going to uplift the autoprogrammer project till the upcoming CoreHard++ conference where I'm giving the talk about modern code generation tools (not only autoprogrammer). Regarding your suggestions:

I found what jinja to C++ binding produced a lot of boilerplate code. I replaced jinja with https://github.com/blockspacer/CXTPL

In the production projects I used this tool I generated not only C++ files, but C files, JSON samples etc. as well. So, template engine which is stuck to the C++ isn't a good choice for me. Another point is that I can ship templates with the production project, not with the tool. Jinja2 is a widely-used notation, template engine is fast and independent. Lot of the boilerplaite for the reflection isn't a problem till this boilerplate can be generated. :)

I can't find docs about autoprogrammer's C++ interpreter, so i used Cling as C++ interpreter.

Yes, there are no docs except my presentation. One of the reasons is that C++ interperter here is still in progress. Actually, it utilizes the idea of constexpr evaluator from the clang with one but significant addition: it allows mixing of injected and interpretable code. I. e. you can write:

inline void BoostSerializable(meta::ClassInfo dst, const meta::ClassInfo& src)
{
    for (auto& v : src.variables())
        $_inject_v(dst, public) v;

    $_inject_v(dst, public) [&, name="serialize"](auto& ar, unsigned int ver) -> void
    {
        $_constexpr for (auto& v : src.variables())
            $_inject(_) ar & $_v(v.name());
    };
};

Here $_constexpr for (auto& v : src.variables()) will be interpreted in the context of the injected method. I'm not sure the Cling allows such kind of tricks.

I wanted to chain multiple metaclasses, so i added custom C++ attribute syntax, very similar to calling C++ functions.

That's not a problem with the current autoprogrammer implementation: $_class(SomeVisitor, CRTPVisitor<A, B, C>, Interface)

I wanted to create tool not focused on predefined set of source transformation rules.

I've been thinking about the external customization/plugins. But I'm considering something like python (in addition to the Jinja2 templates). Binding isn't a big problem.

@blockspacer
Copy link
Author

blockspacer commented Oct 3, 2019

@flexferrum

  1. about CXTPL output.
    About JSON - i can't imagine useful usage examples with JSON. Can you please provide link to similar tool what can output JSON with some usage examples?
    boilerplate can be generated - that may solve a lot of problems. Can Jinja2Cpp generate boilerplate code?

  2. mixing of injected and interpretable code seems less verbose than current Cling based approach.
    In theory, adding some utility functions or macro may produce similar syntax.

autoprogrammer's syntax seems beautiful, but complex for me. Maybe i`m wrong and some docs / updates will solve complexity issue.

@flexferrum
Copy link
Owner

  1. Unfortunately, no, I can't. It was a proprietary project I worked on in my previous company. There was a jinja2-based template which produced sample JSON settings file based on structs read from the source code.
    Jinja2 itself is a library. It can't generate it without proper binding. For this project I'm considering the three-steps build. On the first step core code generation library is built. Then, on the 2nd step, special bootstrap tool is compiled on the top of the core library. This tool generates all boilerplate code for the project. On the 3rd step main autoprogrammer tool is produced.

  2. May by. BTW, this approach needs special support from the interpreter.

Docs will come up. In some future. :)

@flexferrum
Copy link
Owner

Here is the sample how jinja2 templates can be used for serialization boilerplate code generation:
https://github.com/flexferrum/autoprogrammer/tree/master/test/serialization

@zamazan4ik
Copy link

jinja2cpp/Jinja2Cpp#195

@blockspacer
Copy link
Author

I'm sorry to hear this sad news of @flexferrum 's passing.

If anyone interested in development of tools similar to https://github.com/flexferrum/autoprogrammer or https://github.com/blockspacer/CXXCTP - please contact me. I'll be happy to contribute. E-mail: derofim hosted on yandex.ru

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants