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