Resp is an experimental toy language/compiler for a statically typed Scheme-like language which targets LLVM.
Resp is a toy hobby compiler and is a very, very long way off from being useful for anybody. However, the goals are to be: conceptually simple and elegant (like Scheme), strongly typed and safe (like ML/Haskell), fast (like C), and designed to be pleasant to work with (like Python). It compiles numeric code using native types, and (thanks to LLVM), has competitive performance with C and other natively compiled languages (for e.g. signal processing code).
The (C++) code may be useful as a starting point for others looking to write LLVM compilers. It is currently around 3500 LOC, slightly rough around the edges but pleasant to work with (e.g. the compiler reports errors with line and column in editor-friendly GCC style, there are command line flags to dump the IR at any stage of compilation, etc.)
Download
Resp is not yet released and only exists in SVN:
svn co http://svn.drobilla.net/resp/trunk resp
This is very much relevant to what I’m doing right now, I just have one question — Where is the definition of eval? There is a prototype, but is it defined as LLVM bytecode or something?
There isn’t one. This is currently very much a static compiler. The implementation needs to be fleshed out so you can work with an AST (i.e. lists) in the language before something like eval would be possible.
In other words, it’s not really a LISP or Scheme-like at all at the moment, aside from looking LISPey.
I see. Also, how much of a runtime do you think a language like Lisp would need? I guess the basic Form/Cell/Sexp/whatever recursive datatype could be implemented in the compiler, as in “struct Form { Value* Data; Form* Car; Form* Cdr; };”, but I guess that would be problematic with the standard JIT stuff where most things emit pointers to llvm::Value classes, and I haven’t found a way to make those hold recursive data. If one had to implement an eval() at the LLVM bitcode/C++ level, that would be problematic, since it wouldn’t really be much of a compiler then.
If you really just wanted to implement a basic LISP, that would do.
Personally I’d rather make a decent datatype system in the language which would let you define that list type, and others. I love LISP, but lists are a pretty crappy primitive to have to build everything out of, for an actually useful language you need more anyway. As always, the types are the tricky part. You can do recursive types in LLVM, though.
P.S. Your struct is a little odd, the car is the value.
As I understand it, to hold nested lists, the car must also be able to hold a cons cell. At least, that’s how I’ve always done it.
As for recursive types, I’ve seen some documentation in a web-archived version of the LLVM’s Programmer’s Manual about those, but apparently they were deprecated for the new LLVM. I guess I could always just look at the assembler output of the definition of the structure, and build basic primitive functions from there. That, I think, would be the brutest, but probably simplest way to create a tiny little Lisp, just emitting bytecode and linking to it at runtime. The scheme->llvm compiler ( https://github.com/mikea/scheme-llvm ) takes that approach, though you don’t get to do the optimizations provided by LLVM’s IR-emitting classes.