Thread overview
Re: compile-time variables?
May 23, 2007
Fraser
May 23, 2007
Bill Baxter
May 24, 2007
BCS
May 24, 2007
Fraser
May 24, 2007
BCS
Jun 10, 2007
BCS
Jun 01, 2007
vsb
Jun 02, 2007
Robert Fraser
May 23, 2007
I'm trying to create a compile-rime ID that can be used in mixins. The code it's used in is auto-generated, so I can't guarantee anything, and need a separate ID each time the mixin is used (the ID is part of the mixed-in string).

Bill Baxter Wrote:

> Fraser wrote:
> > <snip>
May 23, 2007
Fraser wrote:
> I'm trying to create a compile-rime ID that can be used in mixins. The code it's used in is auto-generated, so I can't guarantee anything, and need a separate ID each time the mixin is used (the ID is part of the mixed-in string).
> 
> Bill Baxter Wrote:
> 
>> Fraser wrote:
>>> <snip>

I see.  Well rule number 1 of CTFE is "no side effects".  So I think that pretty much prevents this from working at compile time, since storing a state somewhere is definitely a persistent side effect.

Are these IDs all in one file?  If not, then in any event you're going to run into trouble making the IDs unique across files with a compile-time technique.

--bb
May 24, 2007
Reply to Bill,

> Fraser wrote:
> 
>> I'm trying to create a compile-rime ID that can be used in mixins.
>> The code it's used in is auto-generated, so I can't guarantee
>> anything, and need a separate ID each time the mixin is used (the ID
>> is part of the mixed-in string).
>> 
>> Bill Baxter Wrote:
>> 
>>> Fraser wrote:
>>> 
>>>> <snip>
>>>> 
> I see.  Well rule number 1 of CTFE is "no side effects".  So I think
> that pretty much prevents this from working at compile time, since
> storing a state somewhere is definitely a persistent side effect.
> 
> Are these IDs all in one file?  If not, then in any event you're going
> to run into trouble making the IDs unique across files with a
> compile-time technique.
> 
> --bb
> 

const int Baz = 0;
pragma(msg, "#define Baz 0\n")
template Foo(A...)
{
    pragma{msg,"template Foo("~convert_Tuple_To_Args_List_And_Specilization!(A)~"){const int Foo = Baz;}\n#define Baz (Baz+1)\n")
}

Use this Foo everywhere you need it (with enough stuff in A to make each use unique).
Compile everything, pipe through cpp, recompile with the resulting code in place of the original code.

I will now retreat to my lair to repent for that blasphemy. <g>


May 24, 2007
BCS Wrote:
> ...
> 
> const int Baz = 0;
> pragma(msg, "#define Baz 0\n")
> template Foo(A...)
> {
>      pragma{msg,"template Foo("~convert_Tuple_To_Args_List_And_Specilization!(A)~"){const
> int Foo = Baz;}\n#define Baz (Baz+1)\n")
> }
> 
> Use this Foo everywhere you need it (with enough stuff in A to make each
> use unique).
> Compile everything, pipe through cpp, recompile with the resulting code in
> place of the original code.
> 
> I will now retreat to my lair to repent for that blasphemy. <g>
> 
> 

Heh; works like a charm! Thanks for that hackery!
May 24, 2007
Reply to Fraser,

> BCS Wrote:
> 
>> ...
>> 
>> const int Baz = 0;
>> pragma(msg, "#define Baz 0\n")
>> template Foo(A...)
>> {
>> pragma{msg,"template
>> Foo("~convert_Tuple_To_Args_List_And_Specilization!(A)~"){const
>> int Foo = Baz;}\n#define Baz (Baz+1)\n")
>> }
>> Use this Foo everywhere you need it (with enough stuff in A to make
>> each
>> use unique).
>> Compile everything, pipe through cpp, recompile with the resulting
>> code in
>> place of the original code.
>> I will now retreat to my lair to repent for that blasphemy. <g>
>> 
> Heh; works like a charm! Thanks for that hackery!
> 

<joking>If you are actually doing this, please send me you name so that I can be sure to never hire you.</joking>


June 01, 2007
May be this helps you.

char[] int2str(int n) {
    if (n == 0)
	return "0";

    char[] result = "";
    int m = 1;
    while (m <= n)
	m *= 10;
    m /= 10;
    while (m > 0) {
	result ~= '0' + n / m;
	n %= m;
	m /= 10;
    }

    return result;
}

char[] unique_var(char[] type, char[] pref, int n) {
    char[] name = pref ~ int2str(n);

    return
	`static if (is(typeof(` ~ name ~ `))) { `
	`    mixin(unique_var("` ~ type ~ `", "` ~ pref ~ `", ` ~ int2str(n + 1) ~ `));`
	`}`
	`else {`
	`    ` ~ type ~ ` ` ~ name ~ `;`
	`}`;
}


void main()
{
    mixin(unique_var("int", "n", 0));
    n0 = 1;
    mixin(unique_var("int", "n", 0));
    n1 = 2;
}
June 02, 2007
SMAAART! Thanks!

vsb Wrote:

> May be this helps you.
> 
> char[] int2str(int n) {
>     if (n == 0)
> 	return "0";
> 
>     char[] result = "";
>     int m = 1;
>     while (m <= n)
> 	m *= 10;
>     m /= 10;
>     while (m > 0) {
> 	result ~= '0' + n / m;
> 	n %= m;
> 	m /= 10;
>     }
> 
>     return result;
> }
> 
> char[] unique_var(char[] type, char[] pref, int n) {
>     char[] name = pref ~ int2str(n);
> 
>     return
> 	`static if (is(typeof(` ~ name ~ `))) { `
> 	`    mixin(unique_var("` ~ type ~ `", "` ~ pref ~ `", ` ~ int2str(n + 1) ~ `));`
> 	`}`
> 	`else {`
> 	`    ` ~ type ~ ` ` ~ name ~ `;`
> 	`}`;
> }
> 
> 
> void main()
> {
>     mixin(unique_var("int", "n", 0));
>     n0 = 1;
>     mixin(unique_var("int", "n", 0));
>     n1 = 2;
> }

June 10, 2007
Reply to Fraser,

> BCS Wrote:
> 
>> ...
>> 
>> const int Baz = 0;
>> pragma(msg, "#define Baz 0\n")
>> template Foo(A...)
>> {
>> pragma{msg,"template
>> Foo("~convert_Tuple_To_Args_List_And_Specilization!(A)~"){const
>> int Foo = Baz;}\n#define Baz (Baz+1)\n")
>> }
>> Use this Foo everywhere you need it (with enough stuff in A to make
>> each
>> use unique).
>> Compile everything, pipe through cpp, recompile with the resulting
>> code in
>> place of the original code.
>> I will now retreat to my lair to repent for that blasphemy. <g>
>> 
> Heh; works like a charm! Thanks for that hackery!
> 


How??? /I/ can't seem to get it working.

I wrote another version instead

module vars;

const char[] prefix = ""; // tag for grep'ing if filtering needed

pragma(msg, prefix~"module vars;");

template Serial(char[] file)
{
	pragma(msg,prefix~"template Serial(char[] file : \""~file~"\"){const int Serial = __LINE__;}");
	const Serial = 0;
}

to build:
1 compile everything in one go, don't link
2 redirect output (with filtering if needed) to vars.d
3 re-compile with vars.d in place of the file this code was in

bud seems to fail when you try this directly but you can work around it with some scripting:

rm -f vars.d vars2.d
build use_hack.d serial.d -nolink -full > vars2.d
mv vars2.d vars.d
build use_hack.d -full
./use_hack