Am 10.08.2011, 20:34 Uhr, schrieb Nick Sabalausky <a@a.a>:
"Adam D. Ruppe" <destructiona...@gmail.com> wrote in message
news:j1ufc0$avd$1...@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 .