Thread overview
Read files at compile time
May 31, 2007
Henrik
May 31, 2007
Deewiant
May 31, 2007
Robert Fraser
May 31, 2007
Henrik
May 31, 2007
Hello!

I have a question or two regarding what is allowed to be executed at compile time and not. Consider the following:

<code>
import std.stdio;
import std.file;
import std.string;


char[][] loadArchetypes( char[] fileName )
{
    char[][] archetypes = splitlines( cast(char[])read( fileName ) );

    return archetypes;
}


void main()
{
    /// Load archetypes
    const char[][] archetypes = loadArchetypes( "archetypes.txt" );

    foreach( archetype; archetypes )
    {
        writefln( archetype );
    }
}

</code>


I suspect that I am not allowed to do this for some reason. I get the very unhelpful error:
Compiling: fileTest.d
Error: variable useWfuncs is used before initialization
Process terminated with status 1 (0 minutes, 0 seconds)
0 errors, 0 warnings


Is it possible to read a file at compile-time in the manner I am trying to do? What does the error message mean?


Yours most confusedly,

Henrik
May 31, 2007
Henrik wrote:
> Is it possible to read a file at compile-time in the manner I am trying to do?

Using splitlines() won't work: it allocates memory, which makes it ineligible for CTFE. It probably does other disallowed stuff, too.

You can use import expressions to read the file into a char[], but splitting on lines at compile time is a bit trickier. You'll need to write a template to do the split.
May 31, 2007
Hi Henrik,

Check out http://www.digitalmars.com/d/expression.html#ImportExpression , which can read files in as compile-time string literals. You'd then need to write a CTFE-compliant string-splitting function and mix that back in. So, you'd have:

mixin(ctfe_split("archetypes", import("file.txt")));

Which should become something like:

char[][3] archetypes = [ "foo", "bar", "baz", ];

Writing the function itself shouldn't be _too_ hard, but there are a number of constructs which make it unable to be executed at compile-time, so ensure it has no side effects.

Regards,
Fraser

Henrik Wrote:

> Hello!
> 
> I have a question or two regarding what is allowed to be executed at compile time and not. Consider the following:
> 
> <code>
> import std.stdio;
> import std.file;
> import std.string;
> 
> 
> char[][] loadArchetypes( char[] fileName )
> {
>     char[][] archetypes = splitlines( cast(char[])read( fileName ) );
> 
>     return archetypes;
> }
> 
> 
> void main()
> {
>     /// Load archetypes
>     const char[][] archetypes = loadArchetypes( "archetypes.txt" );
> 
>     foreach( archetype; archetypes )
>     {
>         writefln( archetype );
>     }
> }
> 
> </code>
> 
> 
> I suspect that I am not allowed to do this for some reason. I get the very unhelpful error:
> Compiling: fileTest.d
> Error: variable useWfuncs is used before initialization
> Process terminated with status 1 (0 minutes, 0 seconds)
> 0 errors, 0 warnings
> 
> 
> Is it possible to read a file at compile-time in the manner I am trying to do? What does the error message mean?
> 
> 
> Yours most confusedly,
> 
> Henrik

May 31, 2007
Robert Fraser Wrote:

> Hi Henrik,
> 
> Check out http://www.digitalmars.com/d/expression.html#ImportExpression , which can read files in as compile-time string literals. You'd then need to write a CTFE-compliant string-splitting function and mix that back in. So, you'd have:
> 
> mixin(ctfe_split("archetypes", import("file.txt")));
> 
> Which should become something like:
> 
> char[][3] archetypes = [ "foo", "bar", "baz", ];


Looks like it could be messy, but worth a try :)

There's not a lot of static information that I want to embed at the moment, but there will be more in the future. It would be nice to be able to avoid large chunks of embedded text/data in the source code by appending it at compile time.