View mode: basic / threaded / horizontal-split · Log in · Help
December 10, 2012
Re: static code generation
> 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() {}
December 10, 2012
Re: static code generation
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.
December 10, 2012
Re: static code generation
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
December 11, 2012
Re: static code generation
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
> 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

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!
December 13, 2012
Re: static code generation
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
> 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

I think the issue I have with all this is that when you put code 
inside a string you lose a lot of compile time features AFAICT.

I can do

q{
   struct _name_
   {
      .... normal struct code ...
   }
} (but everything inside q is a string)

when I want to do

struct _name_
{
     .... normal struct code ...
}

in code. The first is in a string and the second isn't. The 
difference is that with q, I can parse the code and replace 
_name, for example, while in the second case I can't.

It makes it difficult to build up code by mixing stringified code 
and code. It's like, either you have to completely used 
stringified code or not use any at all.


For example, what if I mispell writeln? Sure I get an error but 
it's not at all the correct line number. But if I could use 
"actual code" that then the error should be normal.

>     enum s = q{
>         writelin("hello world");
>     };

in a large program, it could get confusing very quickly because 
essentially all errors will be pointing to oblivion.

This is why I want to all the user to supply actual code(and not 
stringified code) so that errors will show up properly.
December 13, 2012
Re: static code generation
Am 13.12.2012 04:32, schrieb js.mdnq:
> I think the issue I have with all this is that when you put code
> inside a string you lose a lot of compile time features AFAICT.

your right - but...try to come up with an similar ("easy" to implement) 
powerfull solution that is not based on strings and you will see how 
hard it is to get it right - thats the reason for string based mixins
December 13, 2012
Re: static code generation
On Thursday, 13 December 2012 at 06:26:15 UTC, dennis luehring 
wrote:
> Am 13.12.2012 04:32, schrieb js.mdnq:
>> I think the issue I have with all this is that when you put 
>> code
>> inside a string you lose a lot of compile time features AFAICT.
>
> your right - but...try to come up with an similar ("easy" to 
> implement) powerfull solution that is not based on strings and 
> you will see how hard it is to get it right - thats the reason 
> for string based mixins

It's not that I do not want to use strings. I simply want to 
allow the user to insert their own code into places I want them 
too.

q{} helps make this easier but it still mangles the code.

My prototypical example for doing this is simply creating a 
struct with a "custom" name.

struct _name_
{
 ....
}

where _name_ is replaced with some user defined value(it can be 
generated at compile time based on various static settings.

In this case, though, we can't just generate the struct _name 
string and insert it because the mixin will be invalid. The user 
can't supply the block({ }) because there is no way to do so, 
well, unless they do it with a string or q{}, which breaks 
debugging, highlighting, and intellisense to some degree or 
another.

partial structs would work as well as partial mixins.

pmixin(GenStructTag("mystruct")) // (inserts struct "mystruct" at 
this line)
{
 ....
}

which, in this simple example would result in the exact same as 
if the user just did

struct mystruct
{
 ....
}

(BUT realize in both cases the code block {} are identical)

We could do this:

mixin(GenStructTag("mystruct",
q{
 ....
});

and this is a workable solution I suppose... it just doesn't seem 
to work that well in visual D(debugging stepping is broke, 
highlighting is different, etc...). It is better than using a 
string directly though.

There are many simple ways to solve the problem. Pre-processing 
is the easiest to implement but probably doesn't keep in line 
with D's approach. I think partial structs and classes will work 
in my case as I could generate the struct using mixin's then let 
the user add on to them with a partial struct.

Another approach would be possibly to let one pass a code block 
at compile time as a sort of lambda function. A compile time type 
"Code" could be created, which is real code passed to a template 
or mixin but stringified in the process. So:

mixin(GenStructTag("mystruct",
struct _name_
{
 ....
});

Where the 2nd argument is real code(possibly with "markup" or 
meta-tokens) that is stringified in the template mixin which can 
then be processed.

This creates little "pre-processor" like mixin that work on code 
blocks and lets one generate code at compile time.

It might not seem like one is gaining much from leaving out a q{} 
but I think it will make it much easier to debug such things as 
one can actually see the code and step through it, at least what 
is shown. The mixin might mangle the code.

q{} has no idea about code. It's not meant for code. The debugger 
does not know it it's real code or not. But having something like 
c{}, or a Code type, it knows that it's a real code block and not 
a set of arbitrary tokens... in any case q{} is close, but IMO, 
not close enough.
December 13, 2012
Re: static code generation
On 2012-12-09 11:42, 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
> {
>      ....
> }

Sounds like someone wants AST-macros. Yes I know, we don't have a proposal.

-- 
/Jacob Carlborg
December 15, 2012
Re: static code generation
On 12/10/2012 01:43 AM, anonymous wrote:
> Maybe it helps if you see it in action: http://dpaste.dzfl.pl/5d4cb742

Here's a slightly modified version: http://dpaste.dzfl.pl/f2bd1428

regards,
r_m_r
December 15, 2012
Re: static code generation
On Saturday, 15 December 2012 at 15:15:21 UTC, r_m_r wrote:
> On 12/10/2012 01:43 AM, anonymous wrote:
>> Maybe it helps if you see it in action: 
>> http://dpaste.dzfl.pl/5d4cb742

Note that here s1alpha and s2alpha are distinct types.

> Here's a slightly modified version: 
> http://dpaste.dzfl.pl/f2bd1428

Whereas here they are the same.
1 2 3 4 5
Top | Discussion index | About this forum | D home