CTFE - compiling other languages inside D

Marco Leise Marco.Leise at gmx.de
Wed Aug 10 13:32:13 PDT 2011


Am 10.08.2011, 20:34 Uhr, schrieb Nick Sabalausky <a at a.a>:

> "Adam D. Ruppe" <destructionator at gmail.com> wrote in message
> news:j1ufc0$avd$1 at digitalmars.com...
>> Marco Leise wrote:
>>> An unlikely example would be a C compiler within CTFE that takes a
>>> string of C source code and turns it into a D mixin. Is that
>>> possible?
>>
>> It'd be a fair amount of work, but it should be possible.
>>
>> It's tempting to try to implement that as an alternative to D
>> bindings modules.
>>
>> mixin include_C ( import("stdio.h") );
>>
>
> It's a neat possibility, but the downside of that approach, I suspect, is
> that it may slow down compilation.
>
> With that approach, "stdio.h" has to be processed *every* time your  
> program
> is compiled, not just whenever "stdio.h" is changed (which is what you  
> would
> get if the conversion were done with a separate tool and a proper
> buildsystem). Also, I'm sure that CTFE is probably slower than running an
> already compiled tool. It would have to be slower, since it *is*
> interpreted, after all.
>
> This is another reason why CTFE really needs to support IO access (I  
> really
> believe the strict adherance to "CTFE must be *guaranteed* stateless" is  
> a
> mistake. It's right to strongly discourage it, but making the ban this
> strict is taking things too far - similar to Java's ban on pointers).  
> Then,
> include_C could be implemented roughly like this:
>
> string include_C(string filename)
> {
>     auto cache = filename~".cache";
>     if(exists(cache) && timestamp(cache) >= timestamp(filename))
>         return loadFile(cache);
>     else
>     {
>         auto result = convert_C(loadFile(filename));
>         saveFile(cache, result);
>         return result;
>     }
> }
>
> string convert_C(string src)
> {
>     // Do the conversion, possibly even by invoking a pre-compiled tool.
> }
>
> // Only gets processed if stdio.h has changed
> mixin( include_C_file("stdio.h") );
>
> The other big benefit, of course, if that we'd finally get compile-time
> write*() for free.
>
> This would also open the door for a CTFE/library-based buildsystem that
> doesn't require a dedicated "makefile" or equivalent, which is an
> interesting prospect.

Although there are other languages allowing you to call external programs  
during compilation it feels like opening Pandora's box and people will  
start sending code around that does "rm -rf ~/*". Then again, the same  
effect can be accomplished later at runtime so I don't know if there is  
really any objective difference.
I wouldn't mind if there was a compiler switch to enable compile-time I/O  
for exactly the things you mentioned.

For starters, how about this?:
     static string someExternalText = __ctfeReadFile("external.txt");
     static byte[] chipInitialState = __ctfeReadFile("initial_state.bin");
Every external file used in compiling a source file would be added to the  
list of files to check for their modification date in relation to the  
resulting object file. This ensures that the object is recreated when  
either of the sources change. The list can be in a separate file per each  
D source using this feature.

This offers:
- no execution of arbitrary commands
- usual compile-if-newer logic doesn't reinvent the wheel
- compile-time conversion of C headers
- add snippets in domain specific languages by their own respective source  
files
- include microcode blobs and other binary data in your modules if desired

Personally I think this idea rocks, but YMMV :p .


More information about the Digitalmars-d mailing list