Mixin and function template?

Hasan Aljudy hasan.aljudy at gmail.com
Thu Mar 1 02:55:07 PST 2007



renoX wrote:
> Hello,
> 
> I have a template which contain a single function:
> template sputf(A...)
> {
> 	char[] call()
> 	{
> 		auto fd=std.c.stdio.fopen("tmp_file", "w+");
> 		mixin(`fwritef(fd,`~Fmt!(A)~`);`);	
> 		std.c.stdio.fclose(fd);
> 		auto res = cast(char[])read("tmp_file");
> 		return res;
> 	}
> }
> At the call site, I have to do the following:
> 	mixin sputf!("%d{x}") P1;
> 	res = P1.call();
> which is quite ugly, so I'd like to convert the code in a 'function template' but when I do this, I don't manage to call the function without failure..
> Does someone knows how to do it?
> 
> Regards,
> renoX


I wrote some code so that you could print local variables or expressions 
by wrapping them with {{ double braces }} inside the string (this is a 
Django idiom).

The code is not so stable as it doesn't do anything about escaping and 
stuff .. and it's not really tested at all .. except for one use-case;
it's the intended typical usage:

auto name = "hasan";
mixin( bang( "hello {{name}}, how are you?" ) );

the idea is to replace bang("string1 {{expr}} string2") with
writefln( "string1", expr, "string2" );

Here's the code, it's written in an ugly aggressive way because it was 
my first attempt to play with mixins & compile-time functions, so I 
stayed as low-level as possible.
------------
import std.stdio;

char[] parse( char[] string )
{
     char[] result = "";
     int index = 0;
     while( index < string.length )
     {
         //scan for {{
         bool sequence = false;
         int start = index;
         while(index < string.length)
         {
             if( (index < string.length-2) )
             {
                 if( (string[index] == '{') && (string[index+1] == '{') )
                 {
                     sequence = true;
                     break;
                 }
             }
             index++;
         }
         auto raw = string[start..index]; //this holds the contents of 
string up to the first "{{" if there is one.

         if( result.length > 0 )
             result = result ~ ", ";
         result = result ~ `"` ~ raw ~ `"`;

         if( sequence )
         {
             index+= 2;
             start = index;
             //look for }}
             while( (index < string.length-2) )
             {
                 if( (string[index] == '}') && (string[index+1] == '}') )
                     break;
                 index++;
             }
             auto exp = string[start..index];
             result = result ~ ", " ~ exp;
             index += 2;
         }
     }

     return result;
}

char[] bang( char[] expr )
{
     expr = parse(expr);
     return `writefln(` ~ expr ~ `);`;
}

void main()
{
     auto name = "hasan";
     mixin( bang( "hello {{name}}, how are you?" ) );
}
----------



More information about the Digitalmars-d-learn mailing list