Been there, done that --- my own pet programming language (we all do one, or several) is Cowbel, at http://cowbel.sf.net, and it's now on its third incarnation, generating C. The second used LLVM.
The reasons I switched away from LLVM are:
- the LLVM API is huge, not very well documented, and changes radically from version to version.
- LLVM library consumers are not well supported by the project. Frequently what you get when install it is a set of static libraries, which take forever to link against and lead to 150MB binaries.
- LLVM's supported architectures set isn't great yet. C provides a portable, vendor-neutral intermediate language which works everywhere and is easy to read and therefore debug.
- targeting C makes library integration trivial (as your output program can use the library's own headers, which means ABI issues become nonexistent).
I did contemplate a partial switch, where my compiler didn't link against LLVM at all but instead just spat out LLVM bitcode assembly --- but emitting C was the same amount of work and so much more flexible. The only downsides is that C can't do tail calls, and getting the debug information to match up is more work, but that's about it.
(For the interested: Cowbel is an experiment at producing a minimal static duck-typed language --- all types are anonymous; you refer to objects only by their interfaces. The compiler than uses type inference to determine the actual concrete type of the object. This allows it to, e.g. use a single machine word to represent a number if you're never going to do dynamic dispatch on it, which means you don't end up with the weird schizophrenia of C++ and Java where some types are scalars and some are objects and they have different semantics.
It's also an attempt at minimalism; I wanted to remove as many features as possible and still end up with a expressive language with Javascript-ish syntax. I'm really proud of the way I managed to unify scope blocks and objects...
It works beautifully, and produces tight, fast code, but the compiler became unmaintainably complex and needs to be rewritten from scratch, which I haven't done yet.)
Comments
Been there, done that --- my own pet programming language (we all do one, or several) is Cowbel, at http://cowbel.sf.net, and it's now on its third incarnation, generating C. The second used LLVM.
The reasons I switched away from LLVM are:
- the LLVM API is huge, not very well documented, and changes radically from version to version. - LLVM library consumers are not well supported by the project. Frequently what you get when install it is a set of static libraries, which take forever to link against and lead to 150MB binaries. - LLVM's supported architectures set isn't great yet. C provides a portable, vendor-neutral intermediate language which works everywhere and is easy to read and therefore debug. - targeting C makes library integration trivial (as your output program can use the library's own headers, which means ABI issues become nonexistent).
I did contemplate a partial switch, where my compiler didn't link against LLVM at all but instead just spat out LLVM bitcode assembly --- but emitting C was the same amount of work and so much more flexible. The only downsides is that C can't do tail calls, and getting the debug information to match up is more work, but that's about it.
(For the interested: Cowbel is an experiment at producing a minimal static duck-typed language --- all types are anonymous; you refer to objects only by their interfaces. The compiler than uses type inference to determine the actual concrete type of the object. This allows it to, e.g. use a single machine word to represent a number if you're never going to do dynamic dispatch on it, which means you don't end up with the weird schizophrenia of C++ and Java where some types are scalars and some are objects and they have different semantics.
It's also an attempt at minimalism; I wanted to remove as many features as possible and still end up with a expressive language with Javascript-ish syntax. I'm really proud of the way I managed to unify scope blocks and objects...
It works beautifully, and produces tight, fast code, but the compiler became unmaintainably complex and needs to be rewritten from scratch, which I haven't done yet.)
Hi david. I had a look at the cowbel source code. It seems that you have used gc for the generated C code.
Can you please tell me which GC is that ?
I don't. Thanks to all those that do though. Interesting thought experiment, even as a spectator.