View mode: basic / threaded / horizontal-split · Log in · Help
December 09, 2012
static code generation
How can I create mixes of stringified code and code itself?

http://dlang.org/mixin.html

explains how to create structs using strings. But what if I do 
not want to have to encode the whole struct as a string but only 
parts of it?


mixin template GenStruct(stringname)
{
     struct stringname ~ "alpha"
     {
         ....
     }
}


mixin GenStruct!("Helpme");

would be equivalent to do the following

struct Helpmealpha
{
    ....
}
December 09, 2012
Re: static code generation
On Sunday, 9 December 2012 at 10:42:40 UTC, js.mdnq wrote:
> How can I create mixes of stringified code and code itself?
>
> http://dlang.org/mixin.html
>
> explains how to create structs using strings. But what if I do 
> not want to have to encode the whole struct as a string but 
> only parts of it?
>
>
> mixin template GenStruct(stringname)
> {
>      struct stringname ~ "alpha"
>      {
>          ....
>      }
> }
>
>
> mixin GenStruct!("Helpme");
>
> would be equivalent to do the following
>
> struct Helpmealpha
> {
>     ....
> }

I do realize I can probably do this by importing a file into a 
string but I do not want a ton of little files floating around to 
try and manage something relatively simple.
December 09, 2012
Re: static code generation
You can use a templated string-returning function and mix it in:


string codeGenerator(compileTimeArguments, Other...)(Other others)
{
    string result = ...
   (...) // build your code here
    return result;
}

(...)

class C
{
    mixin(codeGenerator!(args)(1, 2, 3));
}
December 09, 2012
Re: static code generation
On Sunday, 9 December 2012 at 11:25:25 UTC, Philippe Sigaud wrote:
> You can use a templated string-returning function and mix it in:
>
>
> string codeGenerator(compileTimeArguments, Other...)(Other 
> others)
> {
>      string result = ...
>     (...) // build your code here
>      return result;
> }
>
> (...)
>
> class C
> {
>      mixin(codeGenerator!(args)(1, 2, 3));
> }

If I'm not mistaken isn't the "code" I'm trying to generate still 
in a string?

(you've unfortunately left out the most important part at 
`//build your code here`)
December 09, 2012
Re: static code generation
On Sunday, 9 December 2012 at 10:42:40 UTC, js.mdnq wrote:
> How can I create mixes of stringified code and code itself?
[...]
> mixin template GenStruct(stringname)
> {
>      struct stringname ~ "alpha"
>      {
>          ....
>      }
> }
>
>
> mixin GenStruct!("Helpme");
>
> would be equivalent to do the following
>
> struct Helpmealpha
> {
>     ....
> }

In this particular case you can do this:
mixin template GenStruct(string stringname)
{
     struct S
     {
         ....
     }
     mixin("alias S " ~ stringname ~ "alpha;");
}
December 09, 2012
Re: static code generation
On Sunday, 9 December 2012 at 19:09:49 UTC, anonymous wrote:
> On Sunday, 9 December 2012 at 10:42:40 UTC, js.mdnq wrote:
>> How can I create mixes of stringified code and code itself?
> [...]
>> mixin template GenStruct(stringname)
>> {
>>     struct stringname ~ "alpha"
>>     {
>>         ....
>>     }
>> }
>>
>>
>> mixin GenStruct!("Helpme");
>>
>> would be equivalent to do the following
>>
>> struct Helpmealpha
>> {
>>    ....
>> }
>
> In this particular case you can do this:
> mixin template GenStruct(string stringname)
> {
>      struct S
>      {
>          ....
>      }
>      mixin("alias S " ~ stringname ~ "alpha;");
> }

But what if I use more than one mixin? I'll have multiple structs
with the same name.
December 09, 2012
Re: static code generation
On Sunday, 9 December 2012 at 19:24:24 UTC, js.mdnq wrote:
>> In this particular case you can do this:
>> mixin template GenStruct(string stringname)
>> {
>>     struct S
>>     {
>>         ....
>>     }
>>     mixin("alias S " ~ stringname ~ "alpha;");
>> }
>
> But what if I use more than one mixin? I'll have multiple 
> structs
> with the same name.

That's not an issue.

"If two different mixins are put in the same scope, and each 
define a declaration with the same name, there is an ambiguity 
error when the declaration is referenced" (note: when it's 
referenced, not when it's declared)
and
"If the name of a declaration in a mixin is the same as a 
declaration in the surrounding scope, the surrounding declaration 
overrides the mixin one"
- http://dlang.org/template-mixin.html
December 09, 2012
Re: static code generation
On Sunday, 9 December 2012 at 19:34:05 UTC, anonymous wrote:
> On Sunday, 9 December 2012 at 19:24:24 UTC, js.mdnq wrote:
>>> In this particular case you can do this:
>>> mixin template GenStruct(string stringname)
>>> {
>>>    struct S
>>>    {
>>>        ....
>>>    }
>>>    mixin("alias S " ~ stringname ~ "alpha;");
>>> }
>>
>> But what if I use more than one mixin? I'll have multiple 
>> structs
>> with the same name.
>
> That's not an issue.
>
> "If two different mixins are put in the same scope, and each 
> define a declaration with the same name, there is an ambiguity 
> error when the declaration is referenced" (note: when it's 
> referenced, not when it's declared)
> and
> "If the name of a declaration in a mixin is the same as a 
> declaration in the surrounding scope, the surrounding 
> declaration overrides the mixin one"
> - http://dlang.org/template-mixin.html


Huh?

No, I mean, if I use the mixin more than once?

GenStruct("s1");
GenStruct("s2");

then I'll have

struct s { } alias s s1;
struct s { } alias s s2;

which will fail or not be what I want, since I want to generate 
the structs s1 and s1.
December 09, 2012
Re: static code generation
If you need a small example for code generation, the following code will 
generate code for translating any enum value into a string:

string EnumToStringGenerate(T,string templateVar = "T", string pre = 
"")(string var){
	string res = "final switch(" ~ var ~ "){";
	foreach(m;__traits(allMembers,T)){
		res ~= "case " ~ templateVar ~ "." ~ m ~ ": return \"" ~ pre ~ m ~ "\";";
	}
	res ~= "}";
	return res;
}

string EnumToString(T)(T value){
	mixin(EnumToStringGenerate!(T)("value"));
}

Example usage:

enum Test
{
  Value1,
  Value2
}

writefln(EnumToString(Test.Value1)); //Will print "Value1"

Kind Regards
Benjamin Thaut
December 09, 2012
Re: static code generation
On Sunday, 9 December 2012 at 19:54:17 UTC, js.mdnq wrote:
> On Sunday, 9 December 2012 at 19:34:05 UTC, anonymous wrote:
>> On Sunday, 9 December 2012 at 19:24:24 UTC, js.mdnq wrote:
>>>> In this particular case you can do this:
>>>> mixin template GenStruct(string stringname)
>>>> {
>>>>   struct S
>>>>   {
>>>>       ....
>>>>   }
>>>>   mixin("alias S " ~ stringname ~ "alpha;");
>>>> }
>>>
>>> But what if I use more than one mixin? I'll have multiple 
>>> structs
>>> with the same name.
>>
>> That's not an issue.
>>
>> "If two different mixins are put in the same scope, and each 
>> define a declaration with the same name, there is an ambiguity 
>> error when the declaration is referenced" (note: when it's 
>> referenced, not when it's declared)
>> and
>> "If the name of a declaration in a mixin is the same as a 
>> declaration in the surrounding scope, the surrounding 
>> declaration overrides the mixin one"
>> - http://dlang.org/template-mixin.html
>
>
> Huh?
>
> No, I mean, if I use the mixin more than once?
>
> GenStruct("s1");
> GenStruct("s2");
>
> then I'll have
>
> struct s { } alias s s1;
> struct s { } alias s s2;
>
> which will fail or not be what I want, since I want to generate 
> the structs s1 and s1.

It won't fail and you'll get s1alpha and s2alpha.

Maybe it helps if you see it in action: 
http://dpaste.dzfl.pl/5d4cb742 (Note: "Result: Success", i.e. the 
asserts hold)
« First   ‹ Prev
1 2 3 4 5
Top | Discussion index | About this forum | D home