I was asked if it was possible to define signals and slots from inside qling. While I hadn't thought about that until then, the solution seemed simple enough and I went ahead and implemented it.
I am just searching for Q_OBJECT in the user's input and, if found, invoke moc, pipe the users input into moc's stdin and, if successful, pass moc's output back into the interpreter. While this solution definitely has its flaws (atm there is no check if the user's input was correct, if the macro is inside a class-definition of if the class is actually derived from QObject), it serves as a starting point. And it's kinda fun :)
This "dumb" method is needed for the run-off-the-mill cling (SVN trunk). I am working on a patch to (hopefully soon) be included in cling that will allow me to install an ASTConsumer and a preprocessor-callback. The ASTConsumer allows me to monitor if a subclass of QObject was defined and the preprocessor-callback allows me to monitor if the Q_OBJECT macro was expanded. If both conditions are met, moc will be invoked. This will certainly be the correct way to go, until then the dumbed-down string-matching version will do its job... kinda... :)
Oh, almost forgot to add a screenshot:
Cheers,
Thomas
Informysik
Montag, 16. Juli 2012
Dienstag, 10. Juli 2012
Multi-line input
Qling has gotten a new feature and while it's nothing too fancy, I think it deserves a blog entry since it kinda touches an interesting detail about cling.
The feature is: multi-line input. Using the conventional line-by-line approach, there were several uncomfortable issues with entering longer chunks of code, like a class definition. It was possible to do the following:
Problem:If you notice a typo in a line that has already been submitted, you have no way to correct it and need to finish the declaration, have clang issue an error and re-type the whole code - this time without typo (which always works as expected, as we all know ;) ).
But let's just cope with that.
(Edit: This statement is not correct, you can enter ".@" to cancel input)
So entering multiple lines has always been possible, cling will notice if my input is complete or not, right? So one might assume that the following works:
Assume "inst" is an instance of a class (let's call it Struct again) implementing the named parameter idiom and your intent is to write sth like:
The problem: Cling has a nice feature. If you enter a statement that has no trailing semicolon, cling will notice that, add the semicolon and print the value of the expression if it is or returns a value.
So this:
Multi-line input to the rescue:
The code-input is not a simple QLineEdit anymore, it is now a QTextEdit with no vertical scrollbar that adjusts its height to fit the text. So you can now enter a whole chunk of code and navigate and edit the (yet unsubmitted) code as you would expect from a proper text-edit. Only after pressing Ctrl+Enter, the code will be submitted.
Note: since the arrow keys are now needed for navigating in the text, you need to press Ctrl+KeyUp and Ctrl+KeyDown to move in the history.
Preprocessor directives such as #include or #define need to be submitted separately from simple statements such as function calls. So in a nutshell if you enter the following:
Whereas the following fails:
The feature is: multi-line input. Using the conventional line-by-line approach, there were several uncomfortable issues with entering longer chunks of code, like a class definition. It was possible to do the following:
After pressing enter after the first line, cling notices that the input was not complete and waits for you to enter more code until the declaration is complete.struct Struct { //press enter int m_i; //press enter Struct():m_i(0){} //press enter }; //press enter
Problem:
But let's just cope with that.
So entering multiple lines has always been possible, cling will notice if my input is complete or not, right? So one might assume that the following works:
Assume "inst" is an instance of a class (let's call it Struct again) implementing the named parameter idiom and your intent is to write sth like:
And you'd assume that it also works this way:inst.setA(1).setB(5).setC("foo");
...as would be legal C++. Well, not quite.inst.setA(1) //press enter .setB(5) //press enter .setC("foo"); //press enter
The problem: Cling has a nice feature. If you enter a statement that has no trailing semicolon, cling will notice that, add the semicolon and print the value of the expression if it is or returns a value.
So this:
will print:functionReturningIntOfValueFive() //note: no semicolon
Thus, after entering the first line in our "inst"-example above will print:(int) 5
because Struct::setA() returns a reference to itself. And qling chokes on the lines after that one.(struct Struct) @0x7fbd13380024
Multi-line input to the rescue:
The code-input is not a simple QLineEdit anymore, it is now a QTextEdit with no vertical scrollbar that adjusts its height to fit the text. So you can now enter a whole chunk of code and navigate and edit the (yet unsubmitted) code as you would expect from a proper text-edit. Only after pressing Ctrl+Enter, the code will be submitted.
Note: since the arrow keys are now needed for navigating in the text, you need to press Ctrl+KeyUp and Ctrl+KeyDown to move in the history.
So, I can just paste whole source-files in the code-edit and be happy?...well, not quite. There is another point worth mentioning:
Preprocessor directives such as #include or #define need to be submitted separately from simple statements such as function calls. So in a nutshell if you enter the following:
the input is split in two chunks: the first 5 lines containing the preprocessor directives and the last line. These two chunks are interpreted separately. That's fine and works, the output is "blubb: 1" as one would expect.#define HULA #ifdef HULA #define BLUBB 1 #endif #include <iostream> std::cout<<"blubb: "<<BLUBB<<std::endl;
Whereas the following fails:
The nitty-gritty details about why this fails will be explained in the next blog-post, this one is getting a little long...#ifdef HULA struct MaybeHula{void foo(){std::cout<<"Hula defined\n";}}; #else struct MaybeHula{void foo(){std::cout<<"Hula NOT defined\n";}}; #endif
Montag, 9. Juli 2012
Meet qling
I just published my first own OSS project called qling. (yay)
Of course, here's the obligatory screenshot:
Check it out at https://github.com/cptG/qling - feedback is welcome!
It's at a very early stage, there are lots of ideas waiting to be implemented.
Have fun,
Thomas
It is a simple Qt interface for cling, a C++ interpreter based on clang.
Interpreted C++ offers the possibility for the user to fiddle with the program using C/C++ - so "scripting" an app with C++ is possible - for whatever reason you'd like to use that. For example CERN's ROOT system uses a C++ interpreter (currently CINT, to be replaced by cling) to "handle and analyze large amounts of data in a very efficient way" - yes, also for finding the Higgs Boson ;)
I see it as a great way to teach C++ (trying stuff, fiddling with C++ without the compile/link cycle and the need to cope tool-chain technicalities for simple examples) and - coupled with the Qt interface - a great way to make first steps with Qt.
Interpreted C++ offers the possibility for the user to fiddle with the program using C/C++ - so "scripting" an app with C++ is possible - for whatever reason you'd like to use that. For example CERN's ROOT system uses a C++ interpreter (currently CINT, to be replaced by cling) to "handle and analyze large amounts of data in a very efficient way" - yes, also for finding the Higgs Boson ;)
I see it as a great way to teach C++ (trying stuff, fiddling with C++ without the compile/link cycle and the need to cope tool-chain technicalities for simple examples) and - coupled with the Qt interface - a great way to make first steps with Qt.
Of course, here's the obligatory screenshot:
Check it out at https://github.com/cptG/qling - feedback is welcome!
It's at a very early stage, there are lots of ideas waiting to be implemented.
Have fun,
Thomas
Abonnieren
Posts (Atom)