Skip to content

Add Pretty structure, a Wadler-Lindig pretty-printer engine #339

@julianhyde

Description

@julianhyde

Add Pretty.java to net.hydromatic.morel.util — a self-contained implementation of Wadler's "prettier printer" algorithm (the Wadler-Lindig variant with Leijen's Column/Nesting extensions).

This is Part B of the morelfmt formatter (#281). It has no dependency on Morel's AST and could later be extracted to a standalone library or reimplemented in Morel itself.

Design

Pretty is a utility class containing the Doc algebraic data type (representing a set of possible layouts for a document) and a layout engine that chooses the best layout given a line-width limit.

Internal Doc variants

Variant Meaning
Empty The empty document
Text(s, doc) Literal string s followed by doc
Line(indent, doc) Newline, then indent spaces, then doc
FlatAlt(primary, flat) primary when broken; flat when flattened
Concat(a, b) a followed by b
Nest(indent, doc) Increase indentation by indent
Union(wide, narrow) Choose wide if it fits, else narrow
Column(fn) Access current column (for align)
Nesting(fn) Access current nesting level

Public combinators

Primitives:
empty, text, line, lineBreak, softLine, softBreak, hardLine

Composition:
beside (concatenation), nest, group (try flattening), align (align to current column), hang, indent, flatten

List combinators:
hsep, vsep, sep, hcat, vcat, cat, fillSep, fillCat, punctuate, encloseSep

Bracketing helpers:
parens, braces, brackets

Rendering:
Pretty.render(int width, Doc doc) → String

Layout algorithm

Best-fit with bounded lookahead via fits. This is the standard approach used in wl-pprint, paiges, and prettyprinter. The Column and Nesting constructors (Leijen's extension) enable align, which is essential for aligning | in match arms and , in tuples/records.

File plan

File Purpose
src/main/java/net/hydromatic/morel/util/Pretty.java Pretty class with Doc type, combinators, and render
src/test/java/net/hydromatic/morel/util/PrettyTest.java Unit tests

Verification

  • Test each combinator (group, nest, align, sep, cat,
    encloseSep) with various widths (e.g. render(40, doc) vs
    render(80, doc)).
  • Verify flatten invariants.
  • mvn test passes.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions