www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - runtime eval / mixin inside a D shell or debugging session

reply "timotheecour" <thelastmammoth gmail.com> writes:
Is anyone working on a runtime eval/mixin functionality?

I would like to be able to support:

int a=0;
mixinRT("load(`libfun.so`)"); //loads symbols + their demangled 
version via an associative array
mixinRT("auto y=myFun(a);"); //creates a Variable y with 'runtime 
type' inferred from myFun's function type
mixinRT("display(y);"); //crashes due to a bug
//the user recompiles libfun.so to correct the bug in display
mixinRT("load(`libfun.so`)"); //reloads symbols but y is still in 
scope.
mixinRT("display(y);"); //works now

This would be extremely useful inside a debugging session (eg 
after a breakpoint) to make full use of D for variable 
introspection, or for quick code development/testing ala 
python/matlab style, and writing a D shell among other scenarios. 
Even a limited subset of D would still be useful in the meantime.
Eg usage: above, myFun takes a long time to compute and we want 
to debug the rest of the program without having to recompute y or 
save it to disk and loading it after each recompilation.

My current/planned approach is to:
* save a dynamic lib libfun.so which contains metadata about each 
funtion using __traits(allMembers), ParameterTypeTuple!(fun), 
ReturnType!fun).
* write a D shell with foreach(line; stdin.byLine()) that:
* loads libfun.so (or whatever the user inputs) via dlopen
* parses each line, extracting function name and arguments (eg: 
"int y=myFun(a);")
* catch segfaults / errors with unix signals so we don't 
interrupt the D shell loop
* find myFun inside libfun's demangled name map and get handle to 
function via dlsym
*  the tricky part is to automatically cast the handle to the 
right function type (given in libfun's metadata), and create a 
variable stack that wraps the variables created in the D shell, 
each variable having a "runtime type" + value. Not sure how to do 
that yet without hardcoding possible input/output types and 
trying them all with a switch. It might be possible with inline 
assembly but help would be welcome.

Is there a simpler way or existing project?


There was some discussion and some initial code for runtime 
loading a shared lib and using the associative array to access 
function by their demangled names:
(http://forum.dlang.org/thread/mailman.370.1342262936.31962.digitalmars-d puremagic.com?page=2)
As for safety concerns raised in that thread, this feature could 
be enabled/disabled with a version compiler switch, but is 
clearly useful for debugging/development.

And then there is flectioned (http://flectioned.kuehne.cn/) which 
should support runtime function call evaluation, eg: call(parent, 
"bar", "Berta", 5); which would call parent("bar","Berta",5). It 
has limitations: code is quite old and doesn't work under latest 
DMD, nor on OSX, and is limited to int or string input arguments, 
etc.

Running a new dmd session passing in the string to compile is not 
a good option as we want to operate on the existing variables in 
scope and avoid disk save/loads of those variables.

Thanks for suggestions!
Sep 02 2012
parent "timotheecour" <thelastmammoth gmail.com> writes:
In the longer run, I'd like this mixinRT to be able to achieve 
something like cling, the C++ interactive interpreter:
http://root.cern.ch/drupal/content/what-cling
http://llvm.org/devmtg/2010-11/Naumann-Cling.pdf
Sep 02 2012