Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Functional Pretty Printer Combinators in Scala

Functional Pretty Printer Combinators in Scala

Talk at fp-syd July 2011

Tony Sloane

August 21, 2014
Tweet

More Decks by Tony Sloane

Other Decks in Programming

Transcript

  1. Anthony M. Sloane Programming Languages Research Group Department of Computing

    Macquarie University Sydney, Australia http://www.comp.mq.edu.au/~asloane https://wiki.mq.edu.au/display/plrg Functional Pretty Printer Combinators in Scala
  2. Linear, bounded, functional pretty printing S. Doaitse Swierstra and Olaf

    Chitil Journal of Functional Programming, 19 (1), 1-16, Jan. 2009 Also useful: Unparsing Expressions With Prefix and Postfix Operators Norman Ramsey Software—Practice and Experience, 28 (12), 1327-1356, Oct.1998
  3. Basic Combinators trait Doc { def <> (e : Doc)

    : Doc } def text (t : String) : Doc def line : Doc def group (d : Doc) : Doc def empty : Doc def nest (d : Doc, j : Indent = defaultIndent) : Doc def pretty (d : Doc, w : Width = defaultWidth) : Layout
  4. Some Derived Combinators def char (c : Char) : Doc

    = ... def space : Doc = char (' ') def semi : Doc = char (';') trait Doc { def <+> (e : Doc) : Doc = this <> space <> e } implicit def stringToDoc (s : String) : Doc = text (s) def value (v : Any) : Doc = string (v.toString) def enclose (l : Doc, d : Doc, r : Doc) : Doc = l <> d <> r def parens (d : Doc) : Doc = enclose (lparen, d, rparen) def ssep (ds : Seq[Doc], sep : Doc) : Doc = fold (ds, (_ <> sep <> _)) def product (p : Any) : Doc = ...
  5. Simple Imperative Language trait ImperativeNode trait Exp extends ImperativeNode case

    class Num (d : Double) extends Exp case class Var (s : Idn) extends Exp case class Neg (e : Exp) extends Exp case class Add (l : Exp, r : Exp) extends Exp case class Sub (l : Exp, r : Exp) extends Exp case class Mul (l : Exp, r : Exp) extends Exp trait Stmt extends ImperativeNode case class Null () extends Stmt case class Seqn (ss : Seq[Stmt]) extends Stmt case class Asgn (v : Var, e : Exp) extends Stmt case class While (e : Exp, b : Stmt) extends Stmt
  6. Pretty Printing Imperative Programs def show (t : ImperativeNode) :

    Doc = t match { case Num (d) => value (d) case Var (s) => s case Neg (e) => parens ("-" <> show (e)) case Add (l, r) => showbin (l, "+", r) case Sub (l, r) => showbin (l, "-", r) case Mul (l, r) => showbin (l, "*", r) case Div (l, r) => showbin (l, "/", r) case Null () => semi case Seqn (ss) => group (braces (nest (line <> ssep (ss map show, line)) <> line)) case Asgn (v, e) => show (v) <+> "=" <+> show (e) <> semi case While (e, b) => "while" <+> parens (show (e)) <> group (nest (line <> show (b))) } def showbin (l : ImperativeNode, op : String, r : ImperativeNode) : Doc = parens (show (l) <+> op <+> show (r))
  7. Doc Indent Width TreeCont TreeCont Tree Cont Pos Dq Out

    Remaining Layout Doc Tree Cont Out 0 w w 0 emptyDq Tree Cont Out "" Implementation (1) pretty
  8. Downloads This Scala implementation is included in the latest release

    of the Kiama language processing library: http://kiama.googlecode.com