March 3, 2019

Implementing a Functional Language: Printing Core

This is an appendix to a series in implementing a functional language. The introduction is here. This is a literate Haskell file - you can download the source here. To load it into GHCi and play around, you can use the following command (you’ll need the source for the Core.Language module as well):

stack --resolver lts-12.2          \
      ghci --package prettyprinter \
           --package text          \
      2019-03-03-printing-core.lhs \

This module exports a single function: print. print pretty prints a CoreProgram, producing a Doc a which can be converted to a final output by the caller. Doc is a type provided by the Prettyprint package.

We print a CoreProgram by printing each of its supercombinator definitions, separating each with a newline.

We print supercombinator by printing its name and binders on one line, and printing the expression body across the rest of the line and possibly further lines below. The body will be indented to preserve the off-side rule.

We print a Core expression by case analysis on its constructors.

pAExpr is like pExpr, but wraps the result in parentheses unless it is a variable or number. This is naive but avoids ambiguity.

sepmap is a convenience function for printing each element in a list separated by spaces.

This is the entire pretty printer. Thanks to the fantastic prettyprinter library, it’s short and quite readable.