www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - static code generation

reply "js.mdnq" <js_adddot+mdng gmail.com> writes:
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
{
     ....
}
Dec 09 2012
next sibling parent reply "js.mdnq" <js_adddot+mdng gmail.com> writes:
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.
Dec 09 2012
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 12/10/2012 01:52 PM, js.mdnq wrote:

 I want to avoid having to wrap the code with "
 " as it disables highlighting and possibly other features(intellisense,
 etc...))

The q{} syntax is supposed to help with that issue. Emacs manages syntax highlighting correctly for the q{} strings: import std.stdio; void main() { enum s = q{ writeln("hello world"); }; mixin (s); // <-- s is a string } Ali
Dec 10 2012
prev sibling next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
--20cf30334fc5b4102f04d069b388
Content-Type: text/plain; charset=UTF-8

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));
}

--20cf30334fc5b4102f04d069b388
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

You can use a templated string-returning function and mix it in:<div><br></=
div><div><br></div><div>string codeGenerator(compileTimeArguments, Other...=
)(Other others)</div><div>{</div><div>=C2=A0 =C2=A0 =C2=A0string result =3D=
 ...</div><div>
=C2=A0 =C2=A0 (...) // build your code here</div><div>=C2=A0 =C2=A0 =C2=A0r=
eturn result;</div><div>}</div><div><br></div><div>(...)</div><div><br></di=
v><div>class C</div><div>{</div><div>=C2=A0 =C2=A0 =C2=A0mixin(codeGenerato=
r!(args)(1, 2, 3));</div><div>}</div>
<div><br></div>

--20cf30334fc5b4102f04d069b388--
Dec 09 2012
prev sibling next sibling parent "js.mdnq" <js_adddot+mdng gmail.com> writes:
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`)
Dec 09 2012
prev sibling next sibling parent reply "anonymous" <anonymous example.com> writes:
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;"); }
Dec 09 2012
parent Benjamin Thaut <code benjamin-thaut.de> writes:
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
Dec 09 2012
prev sibling next sibling parent "js.mdnq" <js_adddot+mdng gmail.com> writes:
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.
Dec 09 2012
prev sibling next sibling parent "anonymous" <anonymous example.com> writes:
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
Dec 09 2012
prev sibling next sibling parent "js.mdnq" <js_adddot+mdng gmail.com> writes:
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.
Dec 09 2012
prev sibling next sibling parent "anonymous" <anonymous example.com> writes:
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)
Dec 09 2012
prev sibling next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
--047d7b677700353fa204d08541ed
Content-Type: text/plain; charset=UTF-8

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

Well, yes, but not when you mix it in. It's a string mixin in this case, not a template mixin.
 (you've unfortunately left out the most important part at `//build your
 code here`)

Because it's just simple string operations using the entire language/Phobos/whatever to get the code you want. And then, you mix it in. Anonymous gave you http://dpaste.dzfl.pl/5d4cb742 With a string mixin, this gives: http://dpaste.dzfl.pl/8fc32179 string genStruct(string stringname) { return "struct " ~ stringname ~ " { //.... }"; } mixin(genStruct("s1")); mixin(genStruct("s2")); static assert(is(s1)); static assert(is(s2)); void main() {} --047d7b677700353fa204d08541ed Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"m= argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> If I&#39;m not mistaken isn&#39;t the &quot;code&quot; I&#39;m trying to ge= nerate still in a string?<br></blockquote><div><br></div><div>Well, yes, bu= t not when you mix it in. It&#39;s a string mixin in this case, not a templ= ate mixin.</div> <div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8= ex;border-left:1px #ccc solid;padding-left:1ex"> <br> (you&#39;ve unfortunately left out the most important part at `//build your= code here`)<br></blockquote><div><br></div><div><br></div><div>Because it&= #39;s just simple string operations using the entire language/Phobos/whatev= er to get the code you want. And then, you mix it in.</div> <div><br></div><div>Anonymous gave you=C2=A0<a href=3D"http://dpaste.dzfl.p= l/5d4cb742">http://dpaste.dzfl.pl/5d4cb742</a></div><div><br></div><div>Wit= h a string mixin, this gives:=C2=A0</div><div><br></div><div><a href=3D"htt= p://dpaste.dzfl.pl/8fc32179">http://dpaste.dzfl.pl/8fc32179</a></div> <div><div><br></div><div>string genStruct(string stringname)</div><div>{</d= iv><div>=C2=A0 =C2=A0 return</div><div>=C2=A0 =C2=A0 &quot;struct &quot; ~ = stringname ~ &quot;</div><div>=C2=A0 =C2=A0 {</div><div>=C2=A0 =C2=A0 =C2= =A0 =C2=A0 //....</div><div>=C2=A0 =C2=A0 }&quot;;</div><div> }</div><div><br></div><div>mixin(genStruct(&quot;s1&quot;));</div><div>mixi= n(genStruct(&quot;s2&quot;));</div><div><br></div><div>static assert(is(s1)= );</div><div>static assert(is(s2));</div><div><br></div><div>void main() {}= </div> <div><br></div></div><div><br></div></div><br> --047d7b677700353fa204d08541ed--
Dec 10 2012
prev sibling next sibling parent "js.mdnq" <js_adddot+mdng gmail.com> writes:
On Monday, 10 December 2012 at 20:17:41 UTC, Philippe Sigaud 
wrote:
 If I'm not mistaken isn't the "code" I'm trying to generate 
 still in a
 string?

Well, yes, but not when you mix it in. It's a string mixin in this case, not a template mixin.

My whole point is not to use strings to insert code but to use code to insert code. (essentially I want to avoid having to wrap the code with " " as it disables highlighting and possibly other features(intellisense, etc...)) We went off on a tangent before as it doesn't really solve my problem. I want to generate a partial struct and global functions and have the user supply the rest of the struct.
Dec 10 2012
prev sibling parent "js.mdnq" <js_adddot+mdng gmail.com> writes:
On Monday, 10 December 2012 at 22:01:37 UTC, Ali Çehreli wrote:
 On 12/10/2012 01:52 PM, js.mdnq wrote:

 I want to avoid having to wrap the code with "
 " as it disables highlighting and possibly other

 etc...))

The q{} syntax is supposed to help with that issue. Emacs manages syntax highlighting correctly for the q{} strings: import std.stdio; void main() { enum s = q{ writeln("hello world"); }; mixin (s); // <-- s is a string } Ali

Thanks, this is definitely a step up. In Visual D, highlighting and intellisense does not work correctly but it does seem to make it easier than using a string directly. (I imagine it is the fault of Visual D for treating the argument of q as different than code) It should, though, let me do what I want easier than the other methods. Thanks again!
Dec 10 2012