the vx-scheme compiler

[ Download ]

When I first started out to write the compiler I was only interested in doing it for its own sake, to get the system running as fast as possible. Naturally, getting the compiler going to the point where it would work for the complete language was more work than I bargained for, and presented some head-scratching puzzles too. For one thing, there was no way for the interpreter, for example, to invoke a compiled procedure safely: doing so would split the current continuation between the interpreter's data structures and the virtual machine in a way that would be pretty difficult to reassemble in such a way as to permit call-with-current-continuation.

That being the case, I was forced to complete the VM implementation to the bitter end. But that opened the possibility of detaching the interpreter in steps, leaving behind a system with the interpreter shorn away and no scheme source to read in order to initialize. To do this the bytecode had to be serialized in a form that could be executed without any help from the interpreter. The compiler emits code in the form of scheme vectors containing ordinary integer opcodes; the VM code contains a routine write-compiled-procedure that tranforms this representation into a static C data structure.

bootstrap.scm, which runs in a special version of the interpreter is linked with a dormant copy of the VM code (to gain access to write-compiled-procedure), sequences the compilation of the compiler Scheme source and a small library of support routines to a C file, _compiler.cpp. At this point, that file can be compiled and linked with the VM, and now you have a Scheme REPL with no interpreter in sight.

For compute-bound tasks, compiled code is more or less twice as fast as the interpreter. For very small programs, or programs that don't loop much, the effort of compiling can outweigh the benefit. (See examples of both behaviors on the benchmark page.

Note that the trick of loading only the compiler and REPL with the VM can be repeated with any Scheme source. scheme-compiler is essentially a precompiled helper to do this: it will transform Scheme code into the C representation of bytecode in one step. Link this with the VM, and now you have compiled scheme code running without either the interpreter or the compiler!

To see this in action, just type make pi. This will take pi.scm from the testcases directory all the way through this process.