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