4 ms·
Just to extend a little: Nearly every widely used (non-lisp) compiler that exists first compiles the program into some sort of intermediate representation that
by Tuna-Fish 16y ago
Just to extend a little: Nearly every widely used (non-lisp) compiler that exists first compiles the program into some sort of intermediate representation that is easier to manipulate and optimize, works on it a while in this form, and then finally compiles that into machine code.
The level of this intermediate representation varies between compilers -- GCC uses a very simplified and strict form of c, while many others use an IR that is closer to assembly. LLVM is not really a competitor to JVM or .NET, but an attempt to define an unified IR that many languages can compile into, be optimized in, and then be compiled into various different machine codes. So that when you write a compiler for a language you only have to write the top layers until your code turns to IR, or if you make a compiler for new platform you only have to write the bottom layers to turn IR into machine code, and in both cases you get free use of all the various IR-level compiler optimizations that have been already built into LLVM.
- illumen 16y agoIndeed. tinycc is one of the only compilers that directly translates to machine code. This makes it compile very quickly, makes the code base smaller, and as a bonus allows it to be a pretty decent c script 'interpreter'. But it also means that it does not optimise as well. Tinycc was originally submitted as the winning entry in an obfuscated C code contest - but is surprisingly readable now. Worth a read.
- sedachv 16y agoMost Lisp compilers have intermediate representations too, although these IRs are still technically Lisp code (although they may not be executable). There's a really good series of blog posts about the IR of the SBCL compiler by Roman Marynchak: http://insidelisp.blogspot.com/search/label/python-book http://insidelisp.blogspot.com/search/label/python-book
- pjscott 16y agoIt sometimes fun to take some random Lisp code and fully expand the macros: (macroexpand '(loop for x in list minimize (sin x))) The output depends on your Lisp compiler, but it can get pretty wild. This is why we have the macroexpand-1 function, to just expand the first macro it finds and stop before all collapses into madness. A compiler writer could get a lot of mileage out of this sort of thing. For example, a LET special form could be implemented as a macro that expands to a call to an anonymous function. All the looping forms could be turned into lambdas and recursion. As long as the compiler can handle that sort of thing nicely, this could really simplify the compiler code.
- StavrosK 16y agoThat clarifies it very much, thank you. From what other commenters said, I gather that you can also use it as an interpreter for the IR, which is, again, very interesting.