Jump to page: 1 2
Thread overview
Translating C macros to D
Jul 10, 2017
Jacob Carlborg
Jul 10, 2017
ketmar
Jul 11, 2017
Jacob Carlborg
Jul 11, 2017
ketmar
Jul 11, 2017
ketmar
Jul 11, 2017
Cym13
Jul 11, 2017
Jacob Carlborg
Jul 11, 2017
Atila Neves
Jul 11, 2017
Cym13
Jul 11, 2017
Andrea Fontana
Jul 11, 2017
Jacob Carlborg
Jul 11, 2017
astian
Jul 11, 2017
Jacob Carlborg
July 10, 2017
I'm trying to come up with a generic way to translate function like C macros to D to be used in DStep.

One problem with macros is that it's not possible, by just looking at the macro, to understand how it's used, what can be passed to it. For example, it's possible to pass values, variables and types to a C macro. But I cannot come up with a signature for a template or function in D that would work for all cases.

Currently DStep translates the macros to templated functions where each parameter has its own template type and are declared as "auto ref". Example:

#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))

Is translated to:

extern (D) auto _IOR(T0, T1, T2)(auto ref T0 type, auto ref T1 nr, auto ref T2 size)
{
    return _IOC(_IOC_READ, type, nr, (_IOC_TYPECHECK(size)));
}

Use as follows:

enum FE_READ_BER = _IOR('o', 70, uint);

The problem with this translation is that it's not possible to pass only a type to this function.

Second try: use alias parameters and only template parameters:

extern (D) auto _IOR(alias type, alias nr, alias size)();

Use as a template:

enum FE_READ_BER = _IOR!('o', 70, uint);

This won't compile either because it's not possible to pass a type to an alias parameter. This is probably a bug that should be fixed.

Third try:

Use the template variadic parameter trick:

extern (D) auto _IOR(Args... /* type, nr, size */)() if (Args.length == 3);

Now the above usage example actually works:

enum FE_READ_BER = _IOR!('o', 70, uint);

Unfortunately it's not possible to take the address of a variable and pass to template variadic parameter:

void foo(Args...)() {}

void main()
{
    int b;
    foo!(b); // passing the variable directly works fine
    foo!(&b); // Error: variable b cannot be read at compile time
}

The strange thing is, if I add another function and pass to the variadic parameter it does work:

void foo(Args...)(Args args)
{
    bar!(args);
}

void bar(Args...)() {}

void main()
{
    int a;
    foo(&a);
}

Does anyone have any other ideas that would work for everything that can be passed to a C macro?

-- 
/Jacob Carlborg
July 10, 2017
Jacob Carlborg wrote:

> Does anyone have any other ideas that would work for everything that can be passed to a C macro?

string mixin with concatenation. this is basically what C macro is anyway.
July 11, 2017
On Monday, 10 July 2017 at 19:42:28 UTC, Jacob Carlborg wrote:
> I'm trying to come up with a generic way to translate function like C macros to D to be used in DStep.
>
> [...]

Is not getting rid of the macro an option? By that I mean translating the code inside the macro (which can admitedly be hard because it doesn't have to be semanticaly correct code due to concatenations but most macros aren't so evil) and add a pass of cpp to the build.

Of course nobody wants to use the C preprocessor on D code, but it would work and I'd prefer ugly code that works and can be refactored than no working translation at all personnaly.
July 11, 2017
On 2017-07-10 21:51, ketmar wrote:

> string mixin with concatenation. this is basically what C macro is anyway.

So you mean pass all arguments to the function as strings and using a string mixin on the call site?

-- 
/Jacob Carlborg
July 11, 2017
On 2017-07-11 03:31, Cym13 wrote:

> Is not getting rid of the macro an option? By that I mean translating the code inside the macro (which can admitedly be hard because it doesn't have to be semanticaly correct code due to concatenations but most macros aren't so evil) and add a pass of cpp to the build.

Not sure I fully understand. Could you give a concrete example? BTW, it might not be possible if the macros are part of the API and we want to keep the D API as close as possible to the C API.

> Of course nobody wants to use the C preprocessor on D code, but it would work and I'd prefer ugly code that works and can be refactored than no working translation at all personnaly.

Are you saying the D code could contain C preprocessor code?

-- 
/Jacob Carlborg
July 11, 2017
Jacob Carlborg wrote:

> On 2017-07-10 21:51, ketmar wrote:
>
>> string mixin with concatenation. this is basically what C macro is anyway.
>
> So you mean pass all arguments to the function as strings and using a string mixin on the call site?

yes. this is what i'm usually doing with C macros -- 'cause it is the easiest way to make 'em "just work".
July 11, 2017
Jacob Carlborg wrote:

> On 2017-07-10 21:51, ketmar wrote:
>
>> string mixin with concatenation. this is basically what C macro is anyway.
>
> So you mean pass all arguments to the function as strings and using a string mixin on the call site?

p.s.: some care should be taken for macros calling other macros, tho -- those should be converted to string concatenations too.
July 11, 2017
On Monday, 10 July 2017 at 19:42:28 UTC, Jacob Carlborg wrote:
> I'm trying to come up with a generic way to translate function like C macros to D to be used in DStep.

Wow Jackob, that would be a really useful feature!

July 11, 2017
On 2017-07-11 09:54, Andrea Fontana wrote:

> Wow Jackob, that would be a really useful feature!

It's already implemented, but it doesn't work for all possible things that can be passed to a C macro.

-- 
/Jacob Carlborg
July 11, 2017
On Tuesday, 11 July 2017 at 06:51:33 UTC, Jacob Carlborg wrote:
> On 2017-07-11 03:31, Cym13 wrote:
>
>> Is not getting rid of the macro an option? By that I mean translating the code inside the macro (which can admitedly be hard because it doesn't have to be semanticaly correct code due to concatenations but most macros aren't so evil) and add a pass of cpp to the build.
>
> Not sure I fully understand. Could you give a concrete example? BTW, it might not be possible if the macros are part of the API and we want to keep the D API as close as possible to the C API.

And in my experience any non-trivial C API requires the pre-processor.

Atila
« First   ‹ Prev
1 2