14 November 2008 11:01 PM (quine | scheme | guile | compilation)
Over the last couple days, I implemented a generic tower of compilers in Guile.
So for example, you have Scheme as a source language, which defines a compiler to GHIL (a scheme-like intermediate language, simpler and without macros), which defines a compiler to GLIL (a lower-level language), which defines a compiler to object code (the byte sequence of VM code).
The compiler takes the source and target language as parameters, and does a depth-first search on the compiler graph to figure out how to get there from here, so to speak.
All well and good you say, but there is a wrinkle, in that sometimes you actually want the result of the computation that you just compiled. This is most clearly the case at the REPL:
scheme@(guile-user)> ,compile 42 Disassembly of #<objcode 871bbd0>: nlocs = 0 nexts = 0 0 (make-int8 42) ;; 42 2 (return) scheme@(guile-user)> 42 $1 = 42
So in order not to pollute my delightfully generic compiler with special cases as to whether we want to actually execute the bytecode, I added a fake language, "value", adding a compiler from objcode to value.
I realized when writing about all of this that there is a subset of values that is valid Scheme, bending my language tower into a circle. I suspected a lurking quine, and after some poking and later inspiration from the internet, I found this one:
((lambda (x) ((compile x) x)) '(lambda (x) ((compile x) x)))