-
-
Notifications
You must be signed in to change notification settings - Fork 47
Format Fmt code generation quickstart
We make extensive use of the Format[0] module via the Fmt[1] API.
As such, you'll need to understand the %a
and @
notation from [0], especially
the section headed "Formatted pretty-printing." Then, we use functions like
pf
and strf
from the Fmt library[1]. On top of that, the @
pretty-printing
specifiers all actually correspond 1-to-1 with commands like open_box
from
the Format library[0]. The boxing system is best described in this explainer
pdf [2], particularly Section 3 ("Format basics"). It's worth noting that someone
was able to make a decent-looking pretty-printer for a subset of Javascript[3] that
might serve as a good reference.
- [0] Format module doc: https://ocaml.org/api/Format.html
- [1] Fmt module doc: https://erratique.ch/software/fmt/doc/Fmt/index.html
- [2] Format Unraveled: https://hal.archives-ouvertes.fr/hal-01503081/file/format-unraveled.pdf
- [3] Javascript pretty-printer https://github.com/Virum/compiler/blob/28e807b842bab5dcf11460c8193dd5b16674951f/JavaScript.ml#L112
Let's break down this line:
pf ppf "@[<hov>template <%a>@]@ " (list ~sep:comma string) templates
First, we should note that we've got the Fmt
module opened sometimes, which is where pf
, list
, comma
, and string
are coming from.
-
pf
is basically the abbreviation forfprintf
. It's ubiquitous - it just means to print to some formatter output (typically writtenppf
) the format string that follows (the one in quotes following). -
ppf
is the output formatter - this could be Fmt.stdout or a string buffer. -
@[<hov> ... @]
is the syntax for opening (and@]
for closing) a "box." Boxes are a formatter concept that allows us to deal with indentation - everything in the box shares the same indentation. (see Format Unraveled or one of the other docs for more details). So in Format strings, you can use@[
to open and@]
to close a box. You can also pass parameters to the opening of the box, which is what this<hov>
is doing. That's telling it to use a horizontal-or-vertical box, which follows some slightly complicated rules but essentially means it tries to flow text across a fixed-width page sort of the way you'd expect - filling up each line before continuing to the next line. -
template <
- this is just a string. It will print the string "template <" -
%a
this is the core of Ocaml's Format system (which Fmt is a wrapper for). This is the compositional format string. So if you're familiar with C style printf, you know that%d
will require one integer argument to follow. OCaml Format also allows %d and %s and all of those from C, but it adds %a, and %a breaks the pattern as it requires two arguments to follow it. The first of those will itself be another formatter (hence the compositionality) and then the second will be the argument to that formatter. Here, those are(list ~sep:comma string)
andtemplates
(just a variable here, containing a list of strings). -
>
here is just the string ">" -
@
here is a "space break" - just outputs a break that will be one space long but could also lead to cutting over to the next line in e.g. anhov
box. There are a bunch of other breaks you can make that start with@
- you may also see@,
or@;
. See the Format library doc for more info. -
(list ~sep:comma string)
This constructs a formatter using theFmt
API.-
Fmt.list
here takes a separator argument and another formatter to compose a formatter that operates over lists of the underlying formatter, separated whatever formatter you pass intosep
. -
~sep
is the syntax for named arguments in ocaml, this one is namedsep
. -
comma
is a built-in Fmt formatter that just prints a ",@ " no matter what is passed in. -
string
is a Fmt builtin and, given a format output and a string, outputs the string. It's probably the simplest possible formatter. So the parenthesized expression expects a format output ("ppf") and a list of strings, and it will comma separate them.
-
-
templates
- just a variable containing a list of strings.