19 comments

[ 5.0 ms ] story [ 49.8 ms ] thread
This is not serious, surely.

It's a simple Python wrapper for gcc. And by simple, I mean, really simple. Meaning the GPL is the biggest file in the source tree.

And it doesn't work:

igcc 0.1 Released under GNU GPL version 2 or later, with NO WARRANTY. Type ".h" for help.

g++> int i = 0;

g++> printf("%d\n", s);

[Compile error - type .e to see it.]

g++> printf("%d\n", i);

[Compile error - type .e to see it.]

g++>

Yes, it does exactly what you think it does. It runs GCC on all the code you've entered.

I've been to the future, and language development does not progress in this direction. Future languages certainly do not have all the elegance of C++ and all the speed of Python.

Instead, why not write a C REPL on the front end of the LLVM Jit!?

No one seems to have even thought of writing a Scheme REPL for the LLVM Jit. And that would be completely doable. Write it in C, use Boehm's garbage collector and the LLVM Jit.

This is exactly what I thought when I started running commands. The "interpreter" is so incredibly slow. Then I looked at the source code and just face-palmed. Python?? Really?
It's slow because C++ compilers are slow. Python isn't so slow as to be the bottleneck here.
That's right. In fact, if Python were used to incrementally compile to assembly, it actually mightn't be too bad. There'd be a relatively short delay every time you pressed the enter key as the new bit got compiled.

The problem with the approach taken is that it compiles everything you ever typed every time you type something. I honestly can't think of a worse combination. C++ is the language, you need a Python interpreter to run it. And there's no incremental compilation, so it just gets slower and slower the more you do.

People who write stuff in Python need to realise that sometimes you can't solve a problem just by wrapping something in Python. Occasionally you need to do some actual work. I'm afraid I see this all too often.

How could this be made better with LLVM and clang? Go!
That would be difficult. You need the ability to be able to recover from errors.

Moreover, you need to be able to redefine things. For example, suppose you defined a type or a function and changed your mind and later decided to redefine them.

I doubt the Clang front-end is designed with this sort of thing in mind.

KDevelop kind of validates c++ code as I type. Also C++ is too "complicated" for a scripting language, if you want to include a C++ kind of scripting in your programs Angel Script is better for that purpose. So the only use i can see for this now is "hello world", or to teach the basics of C++.
I don't know if it has a REPL, but it sure does look interesting, too:

http://root.cern.ch/drupal/content/cint

(also root, of course)

It does. I use it to check quick c questions. It works kind of like gdb's 'p' command, but you can also execute c code by putting it in braces.

Here's an excerpt from my most recent cint repl session:

  cint> {long x = 84bfaad645e2e33f; double * p = &x;}
  Warning: Illegal numerical expression 84bfaad645e2e33f FILE:(tmpfile) LINE:1
  cint> {long x = 0x84bfaad645e2e33f; double * p = &x;}
  cint> p p
  (double*)0x100809480
  cint> p *p
  (double)(-8.31870270613823687e-286)
Unfortunately it is as slow as a dog. I'm not sure I understand what the pressing need for a C interpreter that is slow is. If so, there are two of them out there, including cint. The fact is, there is absolutely no technological reason why a C interpreter has to much slower than compiled C. Even the most stupid, naive implementation you can come up with is still as fast as Python (I know because I tried this last year). And with a proper Jit, it is absolutely possible to make it almost the same speed as compiled C.
The idea behind it, is to compile everything that you don't work right now, and interpret just what you are actually working. At the end of the day you can run the whole code compiled.

Also you lose certain features that are available to the interpretter - but that's okay - that was the point...

CINT is the closest thing I've ever seen to a real C++ REPL. It's actually used quite extensively in the ROOT data analysis environment (REPL, reflection, UI signal/slot mechanism, object persistency, creating dynamically Python bindings, etc.).

As a REPL CINT actually works surprisingly well. Unfortunately it seems to have some problems interpreting certain "advanced" C++ stuff, such as templates and especially code that uses STL heavily. Another problem with it is that since you still need to manage memory manually and have direct access to pointers it's very easy to make CINT (or ROOT) session crash... :(

Btw, the ROOT developers are also working on a new LLVM based C++ interpreter called Cling: http://root.cern.ch/drupal/category/package-context/cling

Thanks for pointing out cling. Unfortunately they don't say which version of Clang/LLVM they build against. Their patches only seem to apply cleanly to version 2.8. But unfortunately it doesn't build for me. I also tried building it against 2.7 and 2.9 for good measure, but no cigar.
I got it to work. You have to build against the latest svn of clang and llvm. I personally found parallel make didn't work for me and that I had to apply the two very small patches to the makefiles manually, though the latter may be fixed by now. It looks like a really excellent project, and I can't wait until they have it working the way they want it to!
So given all the negative reviews of this so far- why isnt there a good C++ repl? Surely there is a huge demand.
First of all, C++ is one of the hardest languages to implement — Clang only got to the point where it could compile Boost less than a year ago. The complexity and difficulty of the task severely culls the number of independent parties willing to work on it.

Second, the language syntax and semantics just don't lend themselves very well to a REPL. For example, there is no top-level execution context in C++. Should we pretend like the lines entered into the interpreter are part of main()? That would mean we couldn't do useful things like define functions. And should typing `int foo = 3` lock up the identifier "foo" for use as an int forever, like it would in normal C++, so that we couldn't later write `float foo` or `string foo` without restarting the interpreter ?