Mixin and function template?

renoX renosky at free.fr
Thu Mar 1 13:12:16 PST 2007


Hasan Aljudy a écrit :
> 
> 
> 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).

Thanks for your code, the syntax I used is inspired from Ruby #{} except 
that I thought that in printf '%' is the escape char, that's why I'm 
using %s{} or %d{} (and %{ as equivalent to '{')

We're doing more or less the same thing, except that my implementation 
takes a tuple instead of just one string which allows to be a little bit 
compatible with printf: mixin(putf!("%d",x)) works.

But I have a hard time making the equivalent of for format/sprintf..

renoX


> 
> 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