We present a compiler construction method for modern programming languages. Our approach is capable of supporting programming language features such as closures, various function call mechanisms, first-class continuations, and exception handling. The key techniques are: a modular way to construct interpreters and thus specify the programming language semantics, an effective means to overcome the interpretive overhead, and a common back-end to ensure efficient code generation.
To demonstrate some of these techniques, we adapt the back-end of the SML/NJ system and use it in a compiler for the lazy functional language Haskell. We compare the performance of the resulting compiler with that of the hand-coded Glasgow Haskell Compiler.