www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Translating C macros to D

reply Jacob Carlborg <doob me.com> writes:
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
Jul 10 2017
next sibling parent reply ketmar <ketmar ketmar.no-ip.org> writes:
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.
Jul 10 2017
parent reply Jacob Carlborg <doob me.com> writes:
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
Jul 10 2017
next sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
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".
Jul 11 2017
prev sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
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.
Jul 11 2017
prev sibling next sibling parent reply Cym13 <cpicard openmailbox.org> writes:
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.
Jul 10 2017
parent reply Jacob Carlborg <doob me.com> writes:
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
Jul 10 2017
next sibling parent Atila Neves <atila.neves gmail.com> writes:
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
Jul 11 2017
prev sibling parent Cym13 <cpicard openmailbox.org> writes:
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.
 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?
Yeah, the C preprocessor (cpp) is a separate program from the compiler, you can use it independently as you would any template language. It does however prepends some infos that you'd have to strip out. Example: $ cat test.d #define MAX(a, b) (a > b ? a : b) void main(string[] args) { import std.stdio; int x = 13; int y = 42; writefln("The max of %d and %d is %d", x, y, MAX(x, y)); } $ cpp test.d void main(string[] args) { import std.stdio; int x = 13; int y = 42; writefln("The max of %d and %d is %d", x, y, (x > y ? x : y)); }
Jul 11 2017
prev sibling next sibling parent reply Andrea Fontana <nospam example.com> writes:
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!
Jul 11 2017
parent Jacob Carlborg <doob me.com> writes:
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
Jul 11 2017
prev sibling parent reply astian <astian local.local> writes:
You might enjoy (or rather not):

  - https://stackoverflow.com/questions/3136686/#10526117
  - https://sourceforge.net/projects/chaos-pp/

How generic you intend to make it?
Jul 11 2017
parent Jacob Carlborg <doob me.com> writes:
On 2017-07-11 20:58, astian wrote:

 How generic you intend to make it?
We'll try to support as much as we can. -- /Jacob Carlborg
Jul 11 2017