Self-modifying code! The real kind!
Jethro via Digitalmars-d
digitalmars-d at puremagic.com
Wed Apr 5 15:21:23 PDT 2017
I think it would be pretty novel to have the concept of self
modifying code.
I have several use cases in D where I have to repeat a process
over and over such as compile, change some line, then recompile
to get the effect.
The main one has to do with mixins.
//version = compiledMixins;
version(compiledMixins)
{
import fooMixedInFile;
} else
{
WriteFile(foo, fooMixedInFile);
ModFile(this, "//version = compiledMixins" => "version =
compiledMixins");
}
This hypothetical code, when compiled behaves like this:
1. evaluates the code string represented by foo and writes it to
the file fooMixinInFile(.d).
2. Modifies the current file and uncomments the version =
compiled Mixins.
3. (hit compile again, or automate somehow)
4. imports fooMixedInFile instead.
What this does, instead of exposing the mixin(foo), is instead
write the mixin to a file and imports that on next build so D can
parse it and return errors properly.
This works well in practice except that WriteFile and ModFile
actually have to be ran at runtime requiring step 3 to also
include a "dummy" run, e.g.,
version(compiledMixins)
{
void main()
{
WriteFile(foo, fooMixedInFile);
ModFile(this, "//version = compiledMixins" => "version =
compiledMixins");
}
} else {
}
Essentially this method allows debugging mixins as code with the
only requirement that one build/dummy run.
The main problem is I create hacks to do it. It would be nice for
a general purpose solution in a nice package. Many would benefit
from being able to debug mixins as if they were code, which the
process above allows. Not only that, which a little big of work,
one could match the output of a mixin to the line of code that
generated it to get an accurate way to find bugs in the mixin
code vs it's output.
I am only talking about string mixins here, of course, and the
import would have to be a valid way to run them(which possibly
may not work for certain types of string mixins... but works in
the majority of cases).
The self modifying code(The ModFile line) is interesting but
probably requires a good D parser to be robust.
I have a feeling that the compiler could do the job internally
much better and completely encapsulate all the work.
Essentially,
1. Evaluate the string mixin(doesn't actually insert it yet).
2. compute hash
3. match hash to mixin's file backing. If not matched or doesn't
exist, write string to file.
4. import the file instead of the mixin code. (or, if you want,
mixin(import(file) but one would need to fixup the the debugging
a little)
This has 3 advantages: 1. Can be done completely by the compiler
when it encounters a mixin statement and doesn't change anything
for the user. 2. Allows both the string generating code to be
debugged(compiler will catch those errors first) and the output
of the mixin(caught on the second compile). 3. No recompilation
required.
Thoughts?
More information about the Digitalmars-d
mailing list