July 18, 2019
On Thursday, 18 July 2019 at 05:02:03 UTC, Iain Buclaw wrote:
> On Wed, 17 Jul 2019 at 23:00, Manu via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>>
>> On Wed, Jul 17, 2019 at 11:45 AM Eduard Staniloiu via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>> > [...]
>>
>> Breaking what? This feature doesn't exist yet! There's nobody with code written against these generated headers...
>>
>
> LDC and GDC builds will break as a result of switching to auto-generated headers, but that's expected when things switch to mechanical naming anyway...  we'll need to update our side of the compiler regardless.

Yep, that's the breaking I was referring to
July 18, 2019
On Wed, Jul 17, 2019 at 9:41 PM Iain Buclaw via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On Wed, 17 Jul 2019 at 20:01, Manu via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> >
> > On Wed, Jul 17, 2019 at 7:29 AM Iain Buclaw via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> > >
> > > On Wed, 17 Jul 2019 at 15:40, Eduard Staniloiu via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> > > >
> > > >
> > > > I have the following question: Can we use C++11 or would that break GDC / LDC? With C++11 we could use `enum class` which would solve this nicely. The issue with `enum class` is that it will break code since not the fields need to be prefixed with the enum name.
> > > >
> > > > But still, what do you think? What are the pros and cons of supporting/using C++11?
> > > >
> > >
> > > No you cannot use C++11, yes it will break GDC bootstrap.
> >
> > This needs to be optional. I can't NOT use C++11 for instance... We could read the --extern-std flag to drive the output perhaps?
>
> I assumed the question was only about dmd headers, and not the tool itself.
>
> Naturally, there should be a way to configure the style or language standards you want the code to be outputted in (and this is another reason why I think a standalone app is better).

A stand-alone app would be unbelievably disappointing. I think I would
not use this if it were a stand-alone app; it would have failed at its
entire value proposition for us. We would stick with writing C++ code
and D as an afterthought because there would be no friction advantage
this way around.
The point is to simplify the build environment, not make it a whole lot worse :/
July 18, 2019
On Wed, Jul 17, 2019 at 9:57 PM Iain Buclaw via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On Wed, 17 Jul 2019 at 22:59, Manu via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> >
> > On Wed, Jul 17, 2019 at 11:40 AM Eduard Staniloiu via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> > >
> > > On Wednesday, 17 July 2019 at 17:41:23 UTC, Manu wrote:
> > > > On Wed, Jul 17, 2019 at 4:40 AM Eduard Staniloiu via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> > > >>
> > > >> enum TestEnum
> > > >> {
> > > >>      TESTENUMaa = 0,
> > > >>      TESTENUMbb = 1
> > > >> };
> > > >
> > > > What in earth is that?
> > >
> > > This is the convention that is used in the manually written headers in order to avoid name clashing between fields of different enums in the C headers
> >
> > Okay... but it's also the worst thing ever, and no real user would
> > want this code to be emit from the compiler ;)
> > Safe to say this is a strictly DMD-specific naming pattern, and I
> > don't think that should be our benchmark for a public-facing feature.
> >
> > A better non-C++11 name might be `TestEnum_aa`?
>
>
> I guess the most typical C/C++98 style would be:
>
> enum xml_status {
>   XML_STATUS_ERROR = 0,
>   XML_STATUS_OK = 1,
>   XML_STATUS_SUSPENDED = 2
> };
>
> Some may want the enum to be called xml_status_flags, or some may want a different prefix for the enum members.

Surely the keys should be created from string material that actually
exists? Applying random formatting to the strings feels pointless to
me. Just prefix the key with the enum name, and `_` is the
overwhelmingly established C identifier separator.
If you want your codebase to feel natural to C in the way you describe
above, then you can write:

enum XML_STATUS
{
  ERROR = 0,
  OK = 1,
  SUSPENDED = 2
}

D has a lot of meta that generates identifiers from things; if there's arbitrary re-formatting rules in this tool, then they would end out being mirrored around the place.
July 19, 2019
Am Thu, 18 Jul 2019 06:41:16 +0200 schrieb Iain Buclaw:

> 
> Naturally, there should be a way to configure the style or language standards you want the code to be outputted in (and this is another reason why I think a standalone app is better).

Has extending the DMD json output, then writing a tool to process that json into c++ .h files been considered?

This way you don't have to worry about compiler API stability and you could make the c++ generation as flexible as you want (and you can target other, non-C++ languages easily).

-- 
Johannes
July 22, 2019
On 2019-07-17 22:59, Manu wrote:

> Okay... but it's also the worst thing ever, and no real user would
> want this code to be emit from the compiler ;)
> Safe to say this is a strictly DMD-specific naming pattern, and I
> don't think that should be our benchmark for a public-facing feature.
> 
> A better non-C++11 name might be `TestEnum_aa`?

In Apple's frameworks, in particular the Objective-C frameworks, they define enums like this:

typedef NS_ENUM(int, MKAnnotationViewDragState)
{
    MKAnnotationViewDragStateNone = 0,
    MKAnnotationViewDragStateStarting,
    MKAnnotationViewDragStateDragging,
    MKAnnotationViewDragStateCanceling,
    MKAnnotationViewDragStateEnding
}

Where NS_ENUM expands, in the above case, to:

typedef int MKAnnotationViewDragState; enum
{
    MKAnnotationViewDragStateNone = 0,
    MKAnnotationViewDragStateStarting,
    MKAnnotationViewDragStateDragging,
    MKAnnotationViewDragStateCanceling,
    MKAnnotationViewDragStateEnding
}

Probably makes it easier to present a nice interface in Swift.

-- 
/Jacob Carlborg
July 22, 2019
On Mon, Jul 22, 2019 at 2:51 AM Jacob Carlborg via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On 2019-07-17 22:59, Manu wrote:
>
> > Okay... but it's also the worst thing ever, and no real user would
> > want this code to be emit from the compiler ;)
> > Safe to say this is a strictly DMD-specific naming pattern, and I
> > don't think that should be our benchmark for a public-facing feature.
> >
> > A better non-C++11 name might be `TestEnum_aa`?
>
> In Apple's frameworks, in particular the Objective-C frameworks, they define enums like this:
>
> typedef NS_ENUM(int, MKAnnotationViewDragState)
> {
>      MKAnnotationViewDragStateNone = 0,
>      MKAnnotationViewDragStateStarting,
>      MKAnnotationViewDragStateDragging,
>      MKAnnotationViewDragStateCanceling,
>      MKAnnotationViewDragStateEnding
> }
>
> Where NS_ENUM expands, in the above case, to:
>
> typedef int MKAnnotationViewDragState; enum
> {
>      MKAnnotationViewDragStateNone = 0,
>      MKAnnotationViewDragStateStarting,
>      MKAnnotationViewDragStateDragging,
>      MKAnnotationViewDragStateCanceling,
>      MKAnnotationViewDragStateEnding
> }
>
> Probably makes it easier to present a nice interface in Swift.
>
> --
> /Jacob Carlborg

Great idea!
We can make the generated header emit this:

#ifndef D_ENUM
# define D_ENUM(name, type) enum name
#endif
#ifndef D_ENUM_KEY
# define D_ENUM_KEY(key, enumType) enumType##_##key
#endif
#ifndef D_ENUM_KEY_VAL
# define D_ENUM_KEY_VAL(key, value, enumType) enumType##_##key = value
#endif

D_ENUM(DEnum, int)
{
  D_ENUM_KEY(A, DEnum),
  D_ENUM_KEY_VAL(B, 10, DEnum),
};



And then someone can override those with:

#define D_ENUM(name, type) enum class name : type
#define D_ENUM_KEY(name, enumType) name
#define D_ENUM_KEY_VAL(name, value, enumType) name = value

#include "my_d_header.h"



And for over-powered win, define the macros like this:

# define D_ENUM(name, lower, upper, type) ...
# define D_ENUM_KEY(key, keyLower, keyUpper, type, typeLower, typeUpper) ...

And then the header emits:
D_ENUM(DEnum, denum, DENUM, int)
{
  D_ENUM_KEY(MyKey, mykey, MYKEY, DEnum, denum, DENUM),
}

This allows maximum flexibility! It can support the D compilers weird naming strategy without adding additional options to the compiler.
July 29, 2019
On Thursday, 18 July 2019 at 18:56:28 UTC, Manu wrote:
> A stand-alone app would be unbelievably disappointing. I think I would
> not use this if it were a stand-alone app; it would have failed at its
> entire value proposition for us. We would stick with writing C++ code
> and D as an afterthought because there would be no friction advantage
> this way around.
> The point is to simplify the build environment, not make it a whole lot worse :/

I second this. I've tried to create this C++ header feature a few months ago, but had to put it aside for lack of time. But the compiler frontend provides a lot of infrastructure that would need to be duplicated in any potential external tool that it's just going to be easier to have this as part of the compiler itself.

Besides, getting updated C++ headers for virtually free on each D compiler run can eliminate a whole host of potential bugs stemming from mismatched definitions because of incorrectly scripted build tooling. Multi-language/multi-compiler builds are unpleasant enough to automate as it is.
July 29, 2019
On Monday, 22 July 2019 at 18:12:01 UTC, Manu wrote:
> Great idea!
> We can make the generated header emit this:
>
> #ifndef D_ENUM
> # define D_ENUM(name, type) enum name
> #endif
> #ifndef D_ENUM_KEY
> # define D_ENUM_KEY(key, enumType) enumType##_##key
> #endif
> #ifndef D_ENUM_KEY_VAL
> # define D_ENUM_KEY_VAL(key, value, enumType) enumType##_##key = value
> #endif
>
> D_ENUM(DEnum, int)
> {
>   D_ENUM_KEY(A, DEnum),
>   D_ENUM_KEY_VAL(B, 10, DEnum),
> };
>
>
>
> And then someone can override those with:
>
> #define D_ENUM(name, type) enum class name : type
> #define D_ENUM_KEY(name, enumType) name
> #define D_ENUM_KEY_VAL(name, value, enumType) name = value
>
> #include "my_d_header.h"
>
>
>
> And for over-powered win, define the macros like this:
>
> # define D_ENUM(name, lower, upper, type) ...
> # define D_ENUM_KEY(key, keyLower, keyUpper, type, typeLower, typeUpper) ...
>
> And then the header emits:
> D_ENUM(DEnum, denum, DENUM, int)
> {
>   D_ENUM_KEY(MyKey, mykey, MYKEY, DEnum, denum, DENUM),
> }
>
> This allows maximum flexibility! It can support the D compilers weird naming strategy without adding additional options to the compiler.

That's a pretty neat hack!

I'm just worried about two things:
- it makes the generated code harder to read (not that big of a deal)
- if you happen to include headers with conflicting D_ENUM* defines (e.g. a potential 3rd party D wrapper), you might get some nasty surprises :/
July 29, 2019
On Friday, 19 July 2019 at 21:08:12 UTC, Johannes Pfau wrote:
> Am Thu, 18 Jul 2019 06:41:16 +0200 schrieb Iain Buclaw:
>
>> 
>> Naturally, there should be a way to configure the style or language standards you want the code to be outputted in (and this is another reason why I think a standalone app is better).
>
> Has extending the DMD json output, then writing a tool to process that json into c++ .h files been considered?
>
> This way you don't have to worry about compiler API stability and you could make the c++ generation as flexible as you want (and you can target other, non-C++ languages easily).

Any such external tool would have to replicate a pretty decent chunk of the D language AST to cover all the relevant nuances of definitions in D. To me, that sounds like writing a lot of code that duplicates stuff that's already in the compiler.
July 28, 2019
On Sun, Jul 28, 2019 at 5:20 PM Gregor Mückl via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On Monday, 22 July 2019 at 18:12:01 UTC, Manu wrote:
> > Great idea!
> > We can make the generated header emit this:
> >
> > #ifndef D_ENUM
> > # define D_ENUM(name, type) enum name
> > #endif
> > #ifndef D_ENUM_KEY
> > # define D_ENUM_KEY(key, enumType) enumType##_##key
> > #endif
> > #ifndef D_ENUM_KEY_VAL
> > # define D_ENUM_KEY_VAL(key, value, enumType) enumType##_##key
> > = value
> > #endif
> >
> > D_ENUM(DEnum, int)
> > {
> >   D_ENUM_KEY(A, DEnum),
> >   D_ENUM_KEY_VAL(B, 10, DEnum),
> > };
> >
> >
> >
> > And then someone can override those with:
> >
> > #define D_ENUM(name, type) enum class name : type
> > #define D_ENUM_KEY(name, enumType) name
> > #define D_ENUM_KEY_VAL(name, value, enumType) name = value
> >
> > #include "my_d_header.h"
> >
> >
> >
> > And for over-powered win, define the macros like this:
> >
> > # define D_ENUM(name, lower, upper, type) ...
> > # define D_ENUM_KEY(key, keyLower, keyUpper, type, typeLower,
> > typeUpper) ...
> >
> > And then the header emits:
> > D_ENUM(DEnum, denum, DENUM, int)
> > {
> >   D_ENUM_KEY(MyKey, mykey, MYKEY, DEnum, denum, DENUM),
> > }
> >
> > This allows maximum flexibility! It can support the D compilers weird naming strategy without adding additional options to the compiler.
>
> That's a pretty neat hack!
>
> I'm just worried about two things:
> - it makes the generated code harder to read (not that big of a
> deal)

Barely... and a generated header is not really for human consumption either way.

> - if you happen to include headers with conflicting D_ENUM* defines (e.g. a potential 3rd party D wrapper), you might get some nasty surprises :/

C/C++ programmers now how to do macros and what to expect.