The CAPI Manifesto

Timon Gehr timon.gehr at gmx.ch
Sat Oct 22 03:48:40 PDT 2011


On 10/22/2011 01:20 AM, Fawzi Mohamed wrote:
> The main problem with this approach is how to support different versions of a library, or of OS. It quickly becomes difficult to support anything but the latest, or a fixed version.
> It works beautifully for mature libs.
>
> I still cannot avoid thinking that a C frontend automatically generating D modules with the help of recipes would be a better way.
> It will need some manual intervention for "difficult" cases, mainly giving manual translation of some macros, but it should be small.
>
> One would set if all the files correspond to modules, or there are just some "main" directories/files.
>
> Some things are easy:
> #define a
> enum { a=true }
> #define b "xyz"
> enum { b="xyz" }
>
> one could be tempted to replace
> 	#ifdef x
> with
> 	static if (is(typeof(x))&&  x)
> and treat other #if in a similar way, but in D a static if must contain a full statement, as its content must be syntactically valid, whereas the C preprocessor does not have this limitation.

D does not have this limitation either. Use string mixins. The only 
difference between C macros and D string mixins is that D is more 
explicit about that the feature is mere string manipulation. There is 
nothing you cannot do with string mixins that is possible with macros. 
(except hijacking existing code or making macro instantiations look like 
function calls for transparent interchangeability, of course).


> The way to work around this, if we create the headers on demand is simple: we already evaluate all #if using the building definitions of the associated C compiler (gcc -E -dD for example) and its default include paths (or directly use it, keeping in account the # line file directives).
>
> real macros are more tricky, for example one could do
>
> #define isSmall(x) (x<2)
> isSmall(T)(T x){
> 	return x<2;
> }


isSmall(x); // use macro in C code

string isSmall(string x) {
         return `{return ~x~`;}`;
}
mixin(isSmall(q{x}); // use macro in D.

or, with Kenji Hara's proposal:

mixin template isSmall(string x){
         enum isSmall = `{return ~x~`;}`;
}

isSmall!q{x} // use macro in D code


>
> #define c(x) { x , #x }

string c(string x){
         return `{ x , q{`~x~`} }`;
}

mixin(c(q{x})); // use macro in D code

or, again, with Kenji Hara's proposal:

mixin template c(string x){
         enum c = `{ x , q{`~x~`} }`;
}

c!q{x} // use macro in D code

multiple parameters would possibly be best handled like this:

mixin template ADD(string x){
     enum cc = {
         string p = x.split(",");
         assert(p.length == 2, "expected 2 parameters");
         return `( `~p[0] ~ '+' ~ p[0] ~ ` )`;
     }();
}

ADD!q{x,y} // use macro in D code



More information about the Digitalmars-d mailing list