static code generation

js.mdnq js_adddot+mdng at gmail.com
Thu Dec 13 03:23:20 PST 2012


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.










More information about the Digitalmars-d-learn mailing list