3e5de399a7
I've just moved the relevant code into the functional-tests dir.
1752 lines
79 KiB
HTML
1752 lines
79 KiB
HTML
<html><head><title>Combinator Formatting</title>
|
|
</head><body bgcolor=white>
|
|
|
|
<h1><span class=subject>Combinator Formatting</span></h1>
|
|
|
|
<style>
|
|
body {
|
|
color: black;
|
|
background-color: white;
|
|
margin-top: 2em;
|
|
margin-left: 10%;
|
|
width: 400pt;
|
|
}
|
|
|
|
pre {
|
|
background-color: beige;
|
|
}
|
|
|
|
pre.scheme {
|
|
background-color: white;
|
|
}
|
|
|
|
.subject {
|
|
}
|
|
|
|
h1 {
|
|
margin-left: -5%;
|
|
margin-top: 2em;
|
|
font-size: large;
|
|
}
|
|
|
|
h2 {
|
|
margin-left: -4%;
|
|
margin-top: 1em;
|
|
font-size: large;
|
|
}
|
|
|
|
h3,h4,h5,h6 {
|
|
margin-left: -3%;
|
|
margin-top: .5em;
|
|
font-size: small;
|
|
}
|
|
|
|
.navigation {
|
|
color: red;
|
|
background-color: beige;
|
|
text-align: right;
|
|
font-style: italic;
|
|
}
|
|
|
|
|
|
.scheme {
|
|
color: brown;
|
|
}
|
|
|
|
.scheme .keyword {
|
|
color: #cc0000;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.scheme .variable {
|
|
color: navy;
|
|
}
|
|
|
|
.scheme .global {
|
|
color: purple;
|
|
}
|
|
|
|
.scheme .constant,.number,.char,.string,.boolean {
|
|
color: green;
|
|
}
|
|
|
|
.scheme .comment {
|
|
color: teal;
|
|
}
|
|
</style>
|
|
<div align=right><a href="http://synthcode.com/">Alex Shinn</a></div>
|
|
<div align=right><a href="http://synthcode.com/scheme/fmt/fmt-0.8.4.tar.gz">Download Version 0.8.4</a></div>
|
|
<p>
|
|
|
|
<br /><br />
|
|
|
|
A library of procedures for formatting Scheme objects to text in
|
|
various ways, and for easily concatenating, composing and extending
|
|
these formatters efficiently without resorting to capturing and
|
|
manipulating intermediate strings.
|
|
<p>
|
|
|
|
<br /><br />
|
|
|
|
<a name="SECTION_1"><h1>1 Table of Contents</h1>
|
|
|
|
|
|
|
|
<ol>
|
|
<li><a href="#SECTION_1">Table of Contents</a>
|
|
<li><a href="#SECTION_2">Installation</a>
|
|
<li><a href="#SECTION_3">Background</a>
|
|
<li><a href="#SECTION_4">Usage</a>
|
|
<li><a href="#SECTION_5">Specification</a>
|
|
<ol>
|
|
<li><a href="#SECTION_5.1">Formatting Objects</a>
|
|
<li><a href="#SECTION_5.2">Formatting Numbers</a>
|
|
<li><a href="#SECTION_5.3">Formatting Space</a>
|
|
<li><a href="#SECTION_5.4">Concatenation</a>
|
|
<li><a href="#SECTION_5.5">Padding and Trimming</a>
|
|
<li><a href="#SECTION_5.6">Format Variables</a>
|
|
<li><a href="#SECTION_5.7">Columnar Formatting</a>
|
|
</ol>
|
|
<li><a href="#SECTION_6">C Formatting</a>
|
|
<ol>
|
|
<li><a href="#SECTION_6.1">C Formatting Basics</a>
|
|
<li><a href="#SECTION_6.2">C Preprocessor Formatting</a>
|
|
<li><a href="#SECTION_6.3">Customizing C Style</a>
|
|
<li><a href="#SECTION_6.4">C Formatter Index</a>
|
|
<li><a href="#SECTION_6.5">C Preprocessor Formatter Index</a>
|
|
<li><a href="#SECTION_6.6">C Types</a>
|
|
<li><a href="#SECTION_6.7">C as S-Expressions</a>
|
|
</ol>
|
|
<li><a href="#SECTION_7">JavaScript Formatting</a>
|
|
<li><a href="#SECTION_8">Formatting with Color</a>
|
|
<li><a href="#SECTION_9">Unicode</a>
|
|
<li><a href="#SECTION_10">Optimizing</a>
|
|
<li><a href="#SECTION_11">Common Lisp Format Cheat Sheet</a>
|
|
<li><a href="#SECTION_12">References</a>
|
|
</ol>
|
|
|
|
<br /><br />
|
|
|
|
<a name="SECTION_2"><h1>2 Installation</h1>
|
|
|
|
Available for Chicken as the <code>fmt</code> egg, providing the <code class=scheme><span class=variable>fmt</span></code>,
|
|
<code class=scheme><span class=variable>fmt-c</span></code>, <code class=scheme><span class=variable>fmt-color</span></code> and <code class=scheme><span class=variable>fmt-unicode</span></code> extensions. To install
|
|
manually for Chicken just run <code>"chicken-setup"</code> in the fmt
|
|
directory.
|
|
<p>
|
|
|
|
For Gauche run <code>"make gauche && make install-gauche"</code>. The modules
|
|
are installed as <code class=scheme><span class=variable>text.fmt</span></code>, <code class=scheme><span class=variable>text.fmt.c</span></code>, <code class=scheme><span class=variable>text.fmt.color</span></code> and
|
|
<code class=scheme><span class=variable>text.fmt.unicode</span></code>.
|
|
<p>
|
|
|
|
For MzScheme you can download and install the latest <code>fmt.plt</code> yourself
|
|
from:
|
|
<p>
|
|
|
|
<a href="http://synthcode.com/scheme/fmt/fmt.plt">http://synthcode.com/scheme/fmt/fmt.plt</a>
|
|
<p>
|
|
|
|
To build the <code>fmt.plt</code> for yourself you can run <code>"make mzscheme"</code>.
|
|
<p>
|
|
|
|
For Scheme48 the package descriptions are in <code>fmt-scheme48.scm</code>:
|
|
<p>
|
|
|
|
<pre class=scheme>
|
|
<span class=variable>></span> ,<span class=variable>config</span> ,<span class=variable>load</span> <span class=variable>fmt-scheme48.scm</span>
|
|
<span class=variable>></span> ,<span class=variable>open</span> <span class=variable>fmt</span>
|
|
</pre>
|
|
<p>
|
|
|
|
For other implementations you'll need to load SRFI's 1, 6, 13, 33
|
|
(sample provided) and 69 (also provided), and then load the following
|
|
files:
|
|
<p>
|
|
|
|
<pre class=scheme>
|
|
(<span class=variable>load</span> <span class=string>"let-optionals.scm"</span>) <span class=comment>; if you don't have LET-OPTIONALS*</span>
|
|
(<span class=variable>load</span> <span class=string>"read-line.scm"</span>) <span class=comment>; if you don't have READ-LINE</span>
|
|
(<span class=variable>load</span> <span class=string>"string-ports.scm"</span>) <span class=comment>; if you don't have CALL-WITH-OUTPUT-STRING</span>
|
|
(<span class=variable>load</span> <span class=string>"make-eq-table.scm"</span>)
|
|
(<span class=variable>load</span> <span class=string>"mantissa.scm"</span>)
|
|
(<span class=variable>load</span> <span class=string>"fmt.scm"</span>)
|
|
(<span class=variable>load</span> <span class=string>"fmt-pretty.scm"</span>) <span class=comment>; optional pretty printing</span>
|
|
(<span class=variable>load</span> <span class=string>"fmt-column.scm"</span>) <span class=comment>; optional columnar output</span>
|
|
(<span class=variable>load</span> <span class=string>"fmt-c.scm"</span>) <span class=comment>; optional C formatting utilities</span>
|
|
(<span class=variable>load</span> <span class=string>"fmt-color.scm"</span>) <span class=comment>; optional color utilities</span>
|
|
(<span class=variable>load</span> <span class=string>"fmt-unicode.scm"</span>) <span class=comment>; optional Unicode-aware formatting,</span>
|
|
<span class=comment>; also requires SRFI-4 or SRFI-66</span>
|
|
</pre>
|
|
<p>
|
|
|
|
<a name="SECTION_3"><h1>3 Background</h1>
|
|
|
|
There are several approaches to text formatting. Building strings to
|
|
<code class=scheme><span class=variable>display</span></code> is not acceptable, since it doesn't scale to very large
|
|
output. The simplest realistic idea, and what people resort to in
|
|
typical portable Scheme, is to interleave <code class=scheme><span class=variable>display</span></code> and <code class=scheme><span class=variable>write</span></code>
|
|
and manual loops, but this is both extremely verbose and doesn't
|
|
compose well. A simple concept such as padding space can't be
|
|
achieved directly without somehow capturing intermediate output.
|
|
<p>
|
|
|
|
The traditional approach is to use templates - typically strings,
|
|
though in theory any object could be used and indeed Emacs' mode-line
|
|
format templates allow arbitrary sexps. Templates can use either
|
|
escape sequences (as in C's <code class=scheme><span class=variable>printf</span></code> and <a href="#BIBITEM_2">CL's</a>
|
|
<code class=scheme><span class=variable>format</span></code>) or pattern matching (as in Visual Basic's <code class=scheme><span class=variable>Format</span></code>,
|
|
<a href="#BIBITEM_6">Perl6's</a> <code class=scheme><span class=variable>form</span></code>, and SQL date formats). The
|
|
primary disadvantage of templates is the relative difficulty (usually
|
|
impossibility) of extending them, their opaqueness, and the
|
|
unreadability that arises with complex formats. Templates are not
|
|
without their advantages, but they are already addressed by other
|
|
libraries such as <a href="#BIBITEM_3">SRFI-28</a> and
|
|
<a href="#BIBITEM_4">SRFI-48</a>.
|
|
<p>
|
|
|
|
This library takes a combinator approach. Formats are nested chains
|
|
of closures, which are called to produce their output as needed.
|
|
The primary goal of this library is to have, first and foremost, a
|
|
maximally expressive and extensible formatting library. The next
|
|
most important goal is scalability - to be able to handle
|
|
arbitrarily large output and not build intermediate results except
|
|
where necessary. The third goal is brevity and ease of use.
|
|
<p>
|
|
|
|
<a name="SECTION_4"><h1>4 Usage</h1>
|
|
|
|
The primary interface is the <code class=scheme><span class=variable>fmt</span></code> procedure:
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=variable><output-dest></span> <span class=variable><format></span> ...)</code>
|
|
<p>
|
|
|
|
where <code class=scheme><span class=variable><output-dest></span></code> has the same semantics as with <code class=scheme><span class=variable>format</span></code> -
|
|
specifically it can be an output-port, <code class=scheme><span class=boolean>#t</span></code> to indicate the current
|
|
output port, or <code class=scheme><span class=boolean>#f</span></code> to accumulate output into a string.
|
|
<p>
|
|
|
|
Each <code class=scheme><span class=variable><format></span></code> should be a format closure as discussed below. As a
|
|
convenience, non-procedure arguments are also allowed and are
|
|
formatted similar to <code class=scheme><span class=variable>display</span></code>, so that
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> <span class=string>"Result: "</span> <span class=variable>res</span> <span class=variable>nl</span>)</code>
|
|
<p>
|
|
|
|
would return the string <code class=scheme><span class=string>"Result: 42n"</span></code>, assuming <code class=scheme><span class=variable>RES</span></code> is bound
|
|
to <code class=scheme><span class=number>42</span></code>.
|
|
<p>
|
|
|
|
<code class=scheme><span class=variable>nl</span></code> is the newline format combinator.
|
|
<p>
|
|
|
|
<a name="SECTION_5"><h1>5 Specification</h1>
|
|
|
|
The procedure names have gone through several variations, and I'm
|
|
still open to new suggestions. The current approach is to use
|
|
abbreviated forms of standard output procedures when defining an
|
|
equivalent format combinator (thus <code class=scheme><span class=variable>display</span></code> becomes <code class=scheme><span class=variable>dsp</span></code> and
|
|
<code class=scheme><span class=variable>write</span></code> becomes <code class=scheme><span class=variable>wrt</span></code>), and to use an <code class=scheme><span class=variable>fmt-</span></code> prefix for
|
|
utilities and less common combinators. Variants of the same formatter
|
|
get a <code class=scheme><span class=variable>/<variant></span></code> suffix.
|
|
<p>
|
|
|
|
<a name="SECTION_5.1"><h2>5.1 Formatting Objects</h2>
|
|
|
|
<h3>(dsp <obj>)</h3>
|
|
|
|
Outputs <code class=scheme><span class=variable><obj></span></code> using <code class=scheme><span class=variable>display</span></code> semantics. Specifically, strings
|
|
are output without surrounding quotes or escaping and characters are
|
|
written as if by <code class=scheme><span class=variable>write-char</span></code>. Other objects are written as with
|
|
<code class=scheme><span class=variable>write</span></code> (including nested strings and chars inside <code class=scheme><span class=variable><obj></span></code>). This
|
|
is the default behavior for top-level formats in <code class=scheme><span class=variable>fmt</span></code>, <code class=scheme><span class=variable>cat</span></code> and
|
|
most other higher-order combinators.
|
|
<p>
|
|
|
|
<h3>(wrt <obj>)</h3>
|
|
|
|
Outputs <code class=scheme><span class=variable><obj></span></code> using <code class=scheme><span class=variable>write</span></code> semantics. Handles shared
|
|
structures as in <a href="#BIBITEM_5">SRFI-38</a>.
|
|
<p>
|
|
|
|
<h3>(wrt/unshared <obj>)</h3>
|
|
|
|
As above, but doesn't handle shared structures. Infinite loops can
|
|
still be avoided if used inside a combinator that truncates data (see
|
|
<code class=scheme><span class=variable>trim</span></code> and <code class=scheme><span class=variable>fit</span></code> below).
|
|
<p>
|
|
|
|
<h3>(pretty <obj>)</h3>
|
|
|
|
Pretty-prints <code class=scheme><span class=variable><obj></span></code>. Also handles shared structures. Unlike many
|
|
other pretty printers, vectors and data lists (lists that don't begin
|
|
with a (nested) symbol), are printed in tabular format when there's
|
|
room, greatly saving vertical space.
|
|
<p>
|
|
|
|
<h3>(pretty/unshared <obj>)</h3>
|
|
|
|
As above but without sharing.
|
|
<p>
|
|
|
|
<h3>(slashified <str> [<quote-ch> <esc-ch> <renamer>])</h3>
|
|
|
|
Outputs the string <code class=scheme><span class=variable><str></span></code>, escaping any quote or escape characters.
|
|
If <code class=scheme><span class=variable><esc-ch></span></code> is <code class=scheme><span class=boolean>#f</span></code> escapes only the <code class=scheme><span class=variable><quote-ch></span></code> by
|
|
doubling it, as in SQL strings and CSV values. If <code class=scheme><span class=variable><renamer></span></code> is
|
|
provided, it should be a procedure of one character which maps that
|
|
character to its escape value, e.g. <code class=scheme><span class=char>#\newline</span> <span class=keyword>=></span> <span class=char>#\n</span></code>, or <code class=scheme><span class=boolean>#f</span></code> if
|
|
there is no escape value.
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>slashified</span> <span class=string>"hi, "bob!""</span>))</code>
|
|
<p>
|
|
|
|
<code class=scheme><span class=keyword>=></span> <span class=string>"hi, "bob!""</span></code>
|
|
<p>
|
|
|
|
<h3>(maybe-slashified <str> <pred> [<quote-ch> <esc-ch> <renamer>])</h3>
|
|
|
|
Like <code class=scheme><span class=variable>slashified</span></code>, but first checks if any quoting is required (by
|
|
the existence of either any quote or escape characters, or any
|
|
character matching <code class=scheme><span class=variable><pred></span></code>), and if so outputs the string in quotes
|
|
and with escapes. Otherwise outputs the string as is.
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>maybe-slashified</span> <span class=string>"foo"</span> <span class=variable>char-whitespace?</span> <span class=char>#\"</span>))</code>
|
|
<p>
|
|
|
|
<code class=scheme><span class=keyword>=></span> <span class=string>"foo"</span></code>
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>maybe-slashified</span> <span class=string>"foo bar"</span> <span class=variable>char-whitespace?</span> <span class=char>#\"</span>))</code>
|
|
<p>
|
|
|
|
<code class=scheme><span class=keyword>=></span> <span class=string>""foo bar""</span></code>
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>maybe-slashified</span> <span class=string>"foo"bar"baz"</span> <span class=variable>char-whitespace?</span> <span class=char>#\"</span>))</code>
|
|
<p>
|
|
|
|
<code class=scheme><span class=keyword>=></span> <span class=string>""foo"bar"baz""</span></code>
|
|
<p>
|
|
|
|
<a name="SECTION_5.2"><h2>5.2 Formatting Numbers</h2>
|
|
|
|
<h3>(num <n> [<radix> <precision> <sign> <comma> <comma-sep> <decimal-sep>])</h3>
|
|
|
|
Formats a single number <code class=scheme><span class=variable><n></span></code>. You can optionally specify any
|
|
<code class=scheme><span class=variable><radix></span></code> from 2 to 36 (even if <code class=scheme><span class=variable><n></span></code> isn't an integer).
|
|
<code class=scheme><span class=variable><precision></span></code> forces a fixed-point format.
|
|
<p>
|
|
|
|
A <code class=scheme><span class=variable><sign></span></code> of <code class=scheme><span class=boolean>#t</span></code> indicates to output a plus sign (+) for positive
|
|
integers. However, if <code class=scheme><span class=variable><sign></span></code> is a character, it means to wrap the
|
|
number with that character and its mirror opposite if the number is
|
|
negative. For example, <code class=scheme><span class=char>#\(</span></code> prints negative numbers in parenthesis,
|
|
financial style: <code class=scheme><span class=number>-3.14</span> <span class=keyword>=></span> (<span class=number>3.14</span>)</code>
|
|
<p>
|
|
|
|
<code class=scheme><span class=variable><comma></span></code> is an integer specifying the number of digits between
|
|
commas. Variable length, as in subcontinental-style, is not yet
|
|
supported.
|
|
<p>
|
|
|
|
<code class=scheme><span class=variable><comma-sep></span></code> is the character to use for commas, defaulting to <code class=scheme><span class=char>#\,</span></code>.
|
|
<p>
|
|
|
|
<code class=scheme><span class=variable><decimal-sep></span></code> is the character to use for decimals, defaulting to
|
|
<code class=scheme><span class=char>#\.</span></code>, or to <code class=scheme><span class=char>#\,</span></code> (European style) if <code class=scheme><span class=variable><comma-sep></span></code> is already
|
|
<code class=scheme><span class=char>#\.</span></code>.
|
|
<p>
|
|
|
|
These parameters may seem unwieldy, but they can also take their
|
|
defaults from state variables, described below.
|
|
<p>
|
|
|
|
<h3>(num/comma <n> [<base> <precision> <sign>])</h3>
|
|
|
|
Shortcut for <code class=scheme><span class=variable>num</span></code> to print with commas.
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>num/comma</span> <span class=number>1234567</span>))</code>
|
|
<p>
|
|
|
|
<code class=scheme><span class=keyword>=></span> <span class=string>"1,234,567"</span></code>
|
|
<p>
|
|
|
|
<h3>(num/si <n> [<base> <suffix>])</h3>
|
|
|
|
Abbreviates <code class=scheme><span class=variable><n></span></code> with an SI suffix as in the -h or --si option to
|
|
many GNU commands. The base defaults to 1024, using suffix names
|
|
like Ki, Mi, Gi, etc. Other bases (e.g. the standard 1000) have the
|
|
suffixes k, M, G, etc.
|
|
<p>
|
|
|
|
The <code class=scheme><span class=variable><suffix></span></code> argument is appended only if an abbreviation is used.
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>num/si</span> <span class=number>608</span>))</code>
|
|
<p>
|
|
|
|
<code class=scheme><span class=keyword>=></span> <span class=string>"608"</span></code>
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>num/si</span> <span class=number>3986</span>))</code>
|
|
<p>
|
|
|
|
<code class=scheme><span class=keyword>=></span> <span class=string>"3.9Ki"</span></code>
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>num/si</span> <span class=number>3986</span> <span class=number>1000</span> <span class=string>"B"</span>))</code>
|
|
<p>
|
|
|
|
<code class=scheme><span class=keyword>=></span> <span class=string>"4kB"</span></code>
|
|
<p>
|
|
|
|
See <a href="http://www.bipm.org/en/si/si_brochure/chapter3/prefixes.html">http://www.bipm.org/en/si/si_brochure/chapter3/prefixes.html</a>.
|
|
<p>
|
|
|
|
<h3>(num/fit <width> <n> . <ARGS>)</h3>
|
|
|
|
Like <code class=scheme><span class=variable>num</span></code>, but if the result doesn't fit in <code class=scheme><span class=variable><width></span></code>, output
|
|
instead a string of hashes (with the current <code class=scheme><span class=variable><precision></span></code>) rather
|
|
than showing an incorrectly truncated number. For example
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>fix</span> <span class=number>2</span> (<span class=variable>num/fit</span> <span class=number>4</span> <span class=number>12.345</span>)))</code>
|
|
<code class=scheme><span class=keyword>=></span> <span class=string>"#.##"</span></code>
|
|
<p>
|
|
|
|
<h3>(num/roman <n>)</h3>
|
|
|
|
Formats the number as a Roman numeral:
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>num/roman</span> <span class=number>1989</span>))</code>
|
|
<code class=scheme><span class=keyword>=></span> <span class=string>"MCMLXXXIX"</span></code>
|
|
<p>
|
|
|
|
<h3>(num/old-roman <n>)</h3>
|
|
|
|
Formats the number as an old-style Roman numeral, without the
|
|
subtraction abbreviation rule:
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>num/old-roman</span> <span class=number>1989</span>))</code>
|
|
<code class=scheme><span class=keyword>=></span> <span class=string>"MDCCCCLXXXVIIII"</span></code>
|
|
<p>
|
|
|
|
<a name="SECTION_5.3"><h2>5.3 Formatting Space</h2>
|
|
|
|
<h3>nl</h3>
|
|
|
|
Outputs a newline.
|
|
<p>
|
|
|
|
<h3>fl</h3>
|
|
|
|
Short for "fresh line," outputs a newline only if we're not already
|
|
at the start of a line.
|
|
<p>
|
|
|
|
<h3>(space-to <column>)</h3>
|
|
|
|
Outputs spaces up to the given <code class=scheme><span class=variable><column></span></code>. If the current column is
|
|
already >= <code class=scheme><span class=variable><column></span></code>, does nothing.
|
|
<p>
|
|
|
|
<h3>(tab-to [<tab-width>])</h3>
|
|
|
|
Outputs spaces up to the next tab stop, using tab stops of width
|
|
<code class=scheme><span class=variable><tab-width></span></code>, which defaults to 8. If already on a tab stop, does
|
|
nothing. If you want to ensure you always tab at least one space, you
|
|
can use <code class=scheme>(<span class=variable>cat</span> <span class=string>" "</span> (<span class=variable>tab-to</span> <span class=variable>width</span>))</code>.
|
|
<p>
|
|
|
|
<h3>fmt-null</h3>
|
|
|
|
Outputs nothing (useful in combinators and as a default noop in
|
|
conditionals).
|
|
<p>
|
|
|
|
<a name="SECTION_5.4"><h2>5.4 Concatenation</h2>
|
|
|
|
<h3>(cat <format> ...)</h3>
|
|
|
|
Concatenates the output of each <code class=scheme><span class=variable><format></span></code>.
|
|
<p>
|
|
|
|
<h3>(apply-cat <list>)</h3>
|
|
|
|
Equivalent to <code class=scheme>(<span class=variable>apply</span> <span class=variable>cat</span> <span class=variable><list></span>)</code> but may be more efficient.
|
|
<p>
|
|
|
|
<h3>(fmt-join <formatter> <list> [<sep>])</h3>
|
|
|
|
Formats each element <code class=scheme><span class=variable><elt></span></code> of <code class=scheme><span class=variable><list></span></code> with <code class=scheme>(<span class=variable><formatter></span>
|
|
<span class=variable><elt></span>)</code>, inserting <code class=scheme><span class=variable><sep></span></code> in between. <code class=scheme><span class=variable><sep></span></code> defaults to the
|
|
empty string, but can be any format.
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>fmt-join</span> <span class=variable>dsp</span> '(<span class=variable>a</span> <span class=variable>b</span> <span class=variable>c</span>) <span class=string>", "</span>))</code>
|
|
<p>
|
|
|
|
<code class=scheme><span class=keyword>=></span> <span class=string>"a, b, c"</span></code>
|
|
<p>
|
|
|
|
<h3>(fmt-join/prefix <formatter> <list> [<sep>])</h3>
|
|
|
|
<h3>(fmt-join/suffix <formatter> <list> [<sep>])</h3>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>fmt-join/prefix</span> <span class=variable>dsp</span> '(<span class=variable>usr</span> <span class=variable>local</span> <span class=variable>bin</span>) <span class=string>"/"</span>))</code>
|
|
<p>
|
|
|
|
<code class=scheme><span class=keyword>=></span> <span class=string>"/usr/local/bin"</span></code>
|
|
<p>
|
|
|
|
As <code class=scheme><span class=variable>fmt-join</span></code>, but inserts <code class=scheme><span class=variable><sep></span></code> before/after every element.
|
|
<p>
|
|
|
|
<h3>(fmt-join/last <formatter> <last-formatter> <list> [<sep>])</h3>
|
|
|
|
As <code class=scheme><span class=variable>fmt-join</span></code>, but the last element of the list is formatted with
|
|
<code class=scheme><span class=variable><last-formatter></span></code> instead.
|
|
<p>
|
|
|
|
<h3>(fmt-join/dot <formatter> <dot-formatter> <list> [<sep>])</h3>
|
|
|
|
As <code class=scheme><span class=variable>fmt-join</span></code>, but if the list is a dotted list, then formats the dotted
|
|
value with <code class=scheme><span class=variable><dot-formatter></span></code> instead.
|
|
<p>
|
|
|
|
<a name="SECTION_5.5"><h2>5.5 Padding and Trimming</h2>
|
|
|
|
<h3>(pad <width> <format> ...)</h3>
|
|
|
|
<h3>(pad/left <width> <format> ...)</h3>
|
|
|
|
<h3>(pad/both <width> <format> ...)</h3>
|
|
|
|
Analogs of SRFI-13 <code class=scheme><span class=variable>string-pad</span></code>, these add extra space to the left,
|
|
right or both sides of the output generated by the <code class=scheme><span class=variable><format></span></code>s to
|
|
pad it to <code class=scheme><span class=variable><width></span></code>. If <code class=scheme><span class=variable><width></span></code> is exceeded has no effect.
|
|
<code class=scheme><span class=variable>pad/both</span></code> will include an extra space on the right side of the
|
|
output if the difference is odd.
|
|
<p>
|
|
|
|
<code class=scheme><span class=variable>pad</span></code> does not accumulate any intermediate data.
|
|
<p>
|
|
|
|
Note these are column-oriented padders, so won't necessarily work
|
|
with multi-line output (padding doesn't seem a likely operation for
|
|
multi-line output).
|
|
<p>
|
|
|
|
<h3>(trim <width> <format> ...)</h3>
|
|
|
|
<h3>(trim/left <width> <format> ...)</h3>
|
|
|
|
<h3>(trim/both <width> <format> ...)</h3>
|
|
|
|
Analogs of SRFI-13 <code class=scheme><span class=variable>string-trim</span></code>, truncates the output of the
|
|
<code class=scheme><span class=variable><format></span></code>s to force it in under <code class=scheme><span class=variable><width></span></code> columns. As soon as
|
|
any of the <code class=scheme><span class=variable><format></span></code>s exceed <code class=scheme><span class=variable><width></span></code>, stop formatting and
|
|
truncate the result, returning control to whoever called <code class=scheme><span class=variable>trim</span></code>. If
|
|
<code class=scheme><span class=variable><width></span></code> is not exceeded has no effect.
|
|
<p>
|
|
|
|
If a truncation ellipse is set (e.g. with the <code class=scheme><span class=variable>ellipses</span></code> procedure
|
|
below), then when any truncation occurs <code class=scheme><span class=variable>trim</span></code> and <code class=scheme><span class=variable>trim/left</span></code>
|
|
will append and prepend the ellipse, respectively. <code class=scheme><span class=variable>trim/both</span></code> will
|
|
both prepend and append. The length of the ellipse will be considered
|
|
when truncating the original string, so that the total width will
|
|
never be longer than <code class=scheme><span class=variable><width></span></code>.
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>ellipses</span> <span class=string>"..."</span> (<span class=variable>trim</span> <span class=number>5</span> <span class=string>"abcde"</span>)))</code>
|
|
<p>
|
|
|
|
<code class=scheme><span class=keyword>=></span> <span class=string>"abcde"</span></code>
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>ellipses</span> <span class=string>"..."</span> (<span class=variable>trim</span> <span class=number>5</span> <span class=string>"abcdef"</span>)))</code>
|
|
<p>
|
|
|
|
<code class=scheme><span class=keyword>=></span> <span class=string>"ab..."</span></code>
|
|
<p>
|
|
|
|
<h3>(trim/length <width> <format> ...)</h3>
|
|
|
|
A variant of <code class=scheme><span class=variable>trim</span></code> which acts on the actual character count rather
|
|
than columns, useful for truncating potentially cyclic data.
|
|
<p>
|
|
|
|
<h3>(fit <width> <format> ...)</h3>
|
|
|
|
<h3>(fit/left <width> <format> ...)</h3>
|
|
|
|
<h3>(fit/both <width> <format> ...)</h3>
|
|
|
|
A combination of <code class=scheme><span class=variable>pad</span></code> and <code class=scheme><span class=variable>trunc</span></code>, ensures the output width is
|
|
exactly <code class=scheme><span class=variable><width></span></code>, truncating if it goes over and padding if it goes
|
|
under.
|
|
<p>
|
|
|
|
<a name="SECTION_5.6"><h2>5.6 Format Variables</h2>
|
|
|
|
You may have noticed many of the formatters are aware of the current
|
|
column. This is because each combinator is actually a procedure of
|
|
one argument, the current format state, which holds basic
|
|
information such as the row, column, and any other information that
|
|
a format combinator may want to keep track of. The basic interface
|
|
is:
|
|
<p>
|
|
|
|
<h3>(fmt-let <name> <value> <format> ...)</h3>
|
|
|
|
<h3>(fmt-bind <name> <value> <format> ...)</h3>
|
|
|
|
<code class=scheme><span class=variable>fmt-let</span></code> sets the name for the duration of the <code class=scheme><span class=variable><format></span></code>s, and
|
|
restores it on return. <code class=scheme><span class=variable>fmt-bind</span></code> sets it without restoring it.
|
|
<p>
|
|
|
|
A convenience control structure can be useful in combination with
|
|
these states:
|
|
<p>
|
|
|
|
<h3>(fmt-if <pred> <pass> [<fail>])</h3>
|
|
|
|
<code class=scheme><span class=variable><pred></span></code> takes one argument (the format state) and returns a boolean
|
|
result. If true, the <code class=scheme><span class=variable><pass></span></code> format is applied to the state,
|
|
otherwise <code class=scheme><span class=variable><fail></span></code> (defaulting to the identity) is applied.
|
|
<p>
|
|
|
|
Many of the previously mentioned combinators have behavior which can
|
|
be altered with state variables. Although <code class=scheme><span class=variable>fmt-let</span></code> and <code class=scheme><span class=variable>fmt-bind</span></code>
|
|
could be used, these common variables have shortcuts:
|
|
<p>
|
|
|
|
<h3>(radix <k> <format> ...)</h3>
|
|
|
|
<h3>(fix <k> <format> ...)</h3>
|
|
|
|
These alter the radix and fixed point precision of numbers output with
|
|
<code class=scheme><span class=variable>dsp</span></code>, <code class=scheme><span class=variable>wrt</span></code>, <code class=scheme><span class=variable>pretty</span></code> or <code class=scheme><span class=variable>num</span></code>. These settings apply
|
|
recursively to all output data structures, so that
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>radix</span> <span class=number>16</span> '(<span class=number>70</span> <span class=number>80</span> <span class=number>90</span>)))</code>
|
|
<p>
|
|
|
|
will return the string <code class=scheme><span class=string>"(#x46 #x50 #x5a)"</span></code>. Note that read/write
|
|
invariance is essential, so for <code class=scheme><span class=variable>dsp</span></code>, <code class=scheme><span class=variable>wrt</span></code> and <code class=scheme><span class=variable>pretty</span></code> the
|
|
radix prefix is always included when not decimal. Use <code class=scheme><span class=variable>num</span></code> if you
|
|
want to format numbers in alternate bases without this prefix. For
|
|
example,
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>radix</span> <span class=number>16</span> <span class=string>"("</span> (<span class=variable>fmt-join</span> <span class=variable>num</span> '(<span class=number>70</span> <span class=number>80</span> <span class=number>90</span>) <span class=string>" "</span>) <span class=string>")"</span>))</code>
|
|
<p>
|
|
|
|
would return <code class=scheme><span class=string>"(46 50 5a)"</span></code>, the same output as above without the
|
|
"#x" radix prefix.
|
|
<p>
|
|
|
|
Note that fixed point formatting supports arbitrary precision in
|
|
implementations with exact non-integral rationals. When trying to
|
|
print inexact numbers more than the machine precision you will
|
|
typically get results like
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>fix</span> <span class=number>30</span> <span class=constant>#i2/3</span>))</code>
|
|
<p>
|
|
|
|
<code class=scheme><span class=keyword>=></span> <span class=string>"0.666666666666666600000000000000"</span></code>
|
|
<p>
|
|
|
|
but with an exact rational it will give you as many digits as you
|
|
request:
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>fix</span> <span class=number>30</span> <span class=number>2/3</span>))</code>
|
|
<p>
|
|
|
|
<code class=scheme><span class=keyword>=></span> <span class=string>"0.666666666666666666666666666667"</span></code>
|
|
<p>
|
|
|
|
<h3>(decimal-align <k> <format> ...)</h3>
|
|
|
|
Specifies an alignment for the decimal place when formatting numbers,
|
|
useful for outputting tables of numbers.
|
|
<p>
|
|
|
|
<pre class=scheme>
|
|
(<span class=keyword>define</span> (<span class=variable>print-angles</span> <span class=variable>x</span>)
|
|
(<span class=variable>fmt-join</span> <span class=variable>num</span> (<span class=variable>list</span> <span class=variable>x</span> (<span class=variable>sin</span> <span class=variable>x</span>) (<span class=variable>cos</span> <span class=variable>x</span>) (<span class=variable>tan</span> <span class=variable>x</span>)) <span class=string>" "</span>))
|
|
|
|
(<span class=variable>fmt</span> <span class=boolean>#t</span> (<span class=variable>decimal-align</span> <span class=number>5</span> (<span class=variable>fix</span> <span class=number>3</span> (<span class=variable>fmt-join/suffix</span> <span class=variable>print-angles</span> (<span class=variable>iota</span> <span class=number>5</span>) <span class=variable>nl</span>))))
|
|
</pre>
|
|
<p>
|
|
|
|
would output
|
|
<p>
|
|
|
|
<pre>
|
|
0.000 0.000 1.000 0.000
|
|
1.000 0.842 0.540 1.557
|
|
2.000 0.909 -0.416 -2.185
|
|
3.000 0.141 -0.990 -0.142
|
|
4.000 -0.757 -0.654 1.158
|
|
</pre>
|
|
<p>
|
|
|
|
<h3>(comma-char <k> <format> ...)</h3>
|
|
|
|
<h3>(decimal-char <k> <format> ...)</h3>
|
|
|
|
<code class=scheme><span class=variable>comma-char</span></code> and <code class=scheme><span class=variable>decimal-char</span></code> set the defaults for number
|
|
formatting.
|
|
<p>
|
|
|
|
<h3>(pad-char <k> <format> ...)</h3>
|
|
|
|
The <code class=scheme><span class=variable>pad-char</span></code> sets the character used by <code class=scheme><span class=variable>space-to</span></code>, <code class=scheme><span class=variable>tab-to</span></code>,
|
|
<code class=scheme><span class=variable>pad/*</span></code>, and <code class=scheme><span class=variable>fit/*</span></code>, and defaults to <code class=scheme><span class=char>#\space</span></code>.
|
|
<p>
|
|
|
|
<pre class=scheme>
|
|
(<span class=keyword>define</span> (<span class=variable>print-table-of-contents</span> <span class=variable>alist</span>)
|
|
(<span class=keyword>define</span> (<span class=variable>print-line</span> <span class=variable>x</span>)
|
|
(<span class=variable>cat</span> (<span class=variable>car</span> <span class=variable>x</span>) (<span class=variable>space-to</span> <span class=number>72</span>) (<span class=variable>pad/left</span> <span class=number>3</span> (<span class=variable>cdr</span> <span class=variable>x</span>))))
|
|
(<span class=variable>fmt</span> <span class=boolean>#t</span> (<span class=variable>pad-char</span> <span class=char>#\.</span> (<span class=variable>fmt-join/suffix</span> <span class=variable>print-line</span> <span class=variable>alist</span> <span class=variable>nl</span>))))
|
|
|
|
(<span class=variable>print-table-of-contents</span>
|
|
'((<span class=string>"An Unexpected Party"</span> . <span class=number>29</span>)
|
|
(<span class=string>"Roast Mutton"</span> . <span class=number>60</span>)
|
|
(<span class=string>"A Short Rest"</span> . <span class=number>87</span>)
|
|
(<span class=string>"Over Hill and Under Hill"</span> . <span class=number>100</span>)
|
|
(<span class=string>"Riddles in the Dark"</span> . <span class=number>115</span>)))
|
|
</pre>
|
|
<p>
|
|
|
|
would output
|
|
<p>
|
|
|
|
<pre>
|
|
An Unexpected Party.....................................................29
|
|
Roast Mutton............................................................60
|
|
A Short Rest............................................................87
|
|
Over Hill and Under Hill...............................................100
|
|
Riddles in the Dark....................................................115
|
|
</pre>
|
|
<p>
|
|
|
|
<h3>(ellipse <ell> <format> ...)</h3>
|
|
|
|
Sets the truncation ellipse to <code class=scheme><span class=variable><ell></span></code>, would should be a string or
|
|
character.
|
|
<p>
|
|
|
|
<h3>(with-width <width> <format> ...)</h3>
|
|
|
|
Sets the maximum column width used by some formatters. The default
|
|
is 78.
|
|
<p>
|
|
|
|
<a name="SECTION_5.7"><h2>5.7 Columnar Formatting</h2>
|
|
|
|
Although <code class=scheme><span class=variable>tab-to</span></code>, <code class=scheme><span class=variable>space-to</span></code> and padding can be used to manually
|
|
align columns to produce table-like output, these can be awkward to
|
|
use. The optional extensions in this section make this easier.
|
|
<p>
|
|
|
|
<h3>(columnar <column> ...)</h3>
|
|
|
|
Formats each <code class=scheme><span class=variable><column></span></code> side-by-side, i.e. as though each were
|
|
formatted separately and then the individual lines concatenated
|
|
together. The current column width is divided evenly among the
|
|
columns, and all but the last column are right-padded. For example
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#t</span> (<span class=variable>columnar</span> (<span class=variable>dsp</span> <span class=string>"abcndefn"</span>) (<span class=variable>dsp</span> <span class=string>"123n456n"</span>)))</code>
|
|
<p>
|
|
|
|
outputs
|
|
<p>
|
|
|
|
<pre>
|
|
abc 123
|
|
def 456
|
|
</pre>
|
|
<p>
|
|
|
|
assuming a 16-char width (the left side gets half the width, or 8
|
|
spaces, and is left aligned). Note that we explicitly use DSP instead
|
|
of the strings directly. This is because <code class=scheme><span class=variable>columnar</span></code> treats raw
|
|
strings as literals inserted into the given location on every line, to
|
|
be used as borders, for example:
|
|
<p>
|
|
|
|
<pre class=scheme>
|
|
(<span class=variable>fmt</span> <span class=boolean>#t</span> (<span class=variable>columnar</span> <span class=string>"/* "</span> (<span class=variable>dsp</span> <span class=string>"abcndefn"</span>)
|
|
<span class=string>" | "</span> (<span class=variable>dsp</span> <span class=string>"123n456n"</span>)
|
|
<span class=string>" */"</span>))
|
|
</pre>
|
|
<p>
|
|
|
|
would output
|
|
<p>
|
|
|
|
<pre>
|
|
/* abc | 123 */
|
|
/* def | 456 */
|
|
</pre>
|
|
<p>
|
|
|
|
You may also prefix any column with any of the symbols <code class=scheme>'<span class=variable>left</span></code>,
|
|
<code class=scheme>'<span class=variable>right</span></code> or <code class=scheme>'<span class=variable>center</span></code> to control the justification. The symbol
|
|
<code class=scheme>'<span class=variable>infinite</span></code> can be used to indicate the column generates an infinite
|
|
stream of output.
|
|
<p>
|
|
|
|
You can further prefix any column with a width modifier. Any
|
|
positive integer is treated as a fixed width, ignoring the available
|
|
width. Any real number between 0 and 1 indicates a fraction of the
|
|
available width (after subtracting out any fixed widths). Columns
|
|
with unspecified width divide up the remaining width evenly.
|
|
<p>
|
|
|
|
Note that <code class=scheme><span class=variable>columnar</span></code> builds its output incrementally, interleaving
|
|
calls to the generators until each has produced a line, then
|
|
concatenating that line together and outputting it. This is important
|
|
because as noted above, some columns may produce an infinite stream of
|
|
output, and in general you may want to format data larger than can fit
|
|
into memory. Thus columnar would be suitable for line numbering a
|
|
file of arbitrary size, or implementing the Unix <code class=scheme><span class=variable>yes</span>(<span class=number>1</span>)</code> command,
|
|
etc.
|
|
<p>
|
|
|
|
As an implementation detail, <code class=scheme><span class=variable>columnar</span></code> uses first-class
|
|
continuations to interleave the column output. The core <code class=scheme><span class=variable>fmt</span></code>
|
|
itself has no knowledge of or special support for <code class=scheme><span class=variable>columnar</span></code>, which
|
|
could complicate and potentially slow down simpler <code class=scheme><span class=variable>fmt</span></code> operations.
|
|
This is a testament to the power of <code class=scheme><span class=variable>call/cc</span></code> - it can be used to
|
|
implement coroutines or arbitrary control structures even where they
|
|
were not planned for.
|
|
<p>
|
|
|
|
<h3>(tabular <column> ...)</h3>
|
|
|
|
Equivalent to <code class=scheme><span class=variable>columnar</span></code> except that each column is padded at least
|
|
to the minimum width required on any of its lines. Thus
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#t</span> (<span class=variable>tabular</span> <span class=string>"|" (dsp "</span><span class=variable>a\\nbc\\ndef\\n</span><span class=string>") "</span>|" (<span class=variable>dsp</span> <span class=string>"123n45n6n"</span>) <span class=string>"|"))</span></code>
|
|
<p>
|
|
|
|
outputs
|
|
<p>
|
|
|
|
<pre>
|
|
|a |123|
|
|
|bc |45 |
|
|
|def|6 |
|
|
</pre>
|
|
<p>
|
|
|
|
This makes it easier to generate tables without knowing widths in
|
|
advance. However, because it requires generating the entire output in
|
|
advance to determine the correct column widths, <code class=scheme><span class=variable>tabular</span></code> cannot
|
|
format a table larger than would fit in memory.
|
|
<p>
|
|
|
|
<h3>(fmt-columns <column> ...)</h3>
|
|
|
|
The low-level formatter on which <code class=scheme><span class=variable>columnar</span></code> is based. Each <code class=scheme><span class=variable><column></span></code>
|
|
must be a list of 2-3 elements:
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable><line-formatter></span> <span class=variable><line-generator></span> [<span class=variable><infinite?></span>])</code>
|
|
<p>
|
|
|
|
where <code class=scheme><span class=variable><line-generator></span></code> is the column generator as above, and the
|
|
<code class=scheme><span class=variable><line-formatter></span></code> is how each line is formatted. Raw concatenation
|
|
of each line is performed, without any spacing or width adjustment.
|
|
<code class=scheme><span class=variable><infinite?></span></code>, if true, indicates this generator produces an
|
|
infinite number of lines and termination should be determined without
|
|
it.
|
|
<p>
|
|
|
|
<h3>(wrap-lines <format> ...)</h3>
|
|
|
|
Behaves like <code class=scheme><span class=variable>cat</span></code>, except text is accumulated and lines are optimally
|
|
wrapped to fit in the current width as in the Unix <code>fmt(1)</code> command.
|
|
<p>
|
|
|
|
<h3>(justify <format> ...)</h3>
|
|
|
|
Like <code class=scheme><span class=variable>wrap-lines</span></code> except the lines are full-justified.
|
|
<p>
|
|
|
|
<pre class=scheme>
|
|
(<span class=keyword>define</span> <span class=variable>func</span>
|
|
'(<span class=keyword>define</span> (<span class=variable>fold</span> <span class=variable>kons</span> <span class=variable>knil</span> <span class=variable>ls</span>)
|
|
(<span class=keyword>let</span> <span class=variable>lp</span> ((<span class=variable>ls</span> <span class=variable>ls</span>) (<span class=variable>acc</span> <span class=variable>knil</span>))
|
|
(<span class=keyword>if</span> (<span class=variable>null?</span> <span class=variable>ls</span>) <span class=variable>acc</span> (<span class=variable>lp</span> (<span class=variable>cdr</span> <span class=variable>ls</span>) (<span class=variable>kons</span> (<span class=variable>car</span> <span class=variable>ls</span>) <span class=variable>acc</span>))))))
|
|
|
|
(<span class=keyword>define</span> <span class=variable>doc</span>
|
|
(<span class=variable>string-append</span>
|
|
<span class=string>"The fundamental list iterator. Applies KONS to each element "</span>
|
|
<span class=string>"of LS and the result of the previous application, beginning "</span>
|
|
<span class=string>"with KNIL. With KONS as CONS and KNIL as '(), equivalent to REVERSE."</span>))
|
|
|
|
(<span class=variable>fmt</span> <span class=boolean>#t</span> (<span class=variable>columnar</span> (<span class=variable>pretty</span> <span class=variable>func</span>) <span class=string>" ; "</span> (<span class=variable>justify</span> <span class=variable>doc</span>)))
|
|
</pre>
|
|
<p>
|
|
|
|
outputs
|
|
<p>
|
|
|
|
<pre>
|
|
(define (fold kons knil ls) ; The fundamental list iterator.
|
|
(let lp ((ls ls) (acc knil)) ; Applies KONS to each element of
|
|
(if (null? ls) ; LS and the result of the previous
|
|
acc ; application, beginning with KNIL.
|
|
(lp (cdr ls) ; With KONS as CONS and KNIL as '(),
|
|
(kons (car ls) acc))))) ; equivalent to REVERSE.
|
|
</pre>
|
|
<p>
|
|
|
|
<h3>(fmt-file <pathname>)</h3>
|
|
|
|
Simply displayes the contents of the file <code class=scheme><span class=variable><pathname></span></code> a line at a
|
|
time, so that in typical formatters such as <code class=scheme><span class=variable>columnar</span></code> only constant
|
|
memory is consumed, making this suitable for formatting files of
|
|
arbitrary size.
|
|
<p>
|
|
|
|
<h3>(line-numbers [<start>])</h3>
|
|
|
|
A convenience utility, just formats an infinite stream of numbers (in
|
|
the current radix) beginning with <code class=scheme><span class=variable><start></span></code>, which defaults to <code class=scheme><span class=number>1</span></code>.
|
|
<p>
|
|
|
|
The Unix <code class=scheme><span class=variable>nl</span>(<span class=number>1</span>)</code> utility could be implemented as:
|
|
<p>
|
|
|
|
<pre class=scheme>
|
|
(<span class=variable>fmt</span> <span class=boolean>#t</span> (<span class=variable>columnar</span> <span class=number>6</span> '<span class=variable>right</span> '<span class=variable>infinite</span> (<span class=variable>line-numbers</span>)
|
|
<span class=string>" "</span> (<span class=variable>fmt-file</span> <span class=string>"read-line.scm"</span>)))
|
|
</pre>
|
|
<p>
|
|
|
|
<pre>
|
|
1
|
|
2 (define (read-line . o)
|
|
3 (let ((port (if (pair? o) (car o) (current-input-port))))
|
|
4 (let lp ((res '()))
|
|
5 (let ((c (read-char port)))
|
|
6 (if (or (eof-object? c) (eqv? c #\newline))
|
|
7 (list->string (reverse res))
|
|
8 (lp (cons c res)))))))
|
|
</pre>
|
|
<p>
|
|
|
|
<a name="SECTION_6"><h1>6 C Formatting</h1>
|
|
|
|
<a name="SECTION_6.1"><h2>6.1 C Formatting Basics</h2>
|
|
|
|
For purposes such as writing wrappers, code-generators, compilers or
|
|
other language tools, people often need to generate or emit C code.
|
|
Without a decent library framework it's difficult to maintain proper
|
|
indentation. In addition, for the Scheme programmer it's tedious to
|
|
work with all the context sensitivities of C, such as the expression
|
|
vs. statement distinction, special rules for writing preprocessor
|
|
macros, and when precedence rules require parenthesis. Fortunately,
|
|
context is one thing this formatting library is good at keeping
|
|
track of. The C formatting interface tries to make it as easy as
|
|
possible to generate C code without getting in your way.
|
|
<p>
|
|
|
|
There are two approaches to using the C formatting extensions -
|
|
procedural and sexp-oriented (described in <a href="#SECTION_6.7">6.7</a>). In the
|
|
procedural interface, C operators are made available as formatters
|
|
with a "c-" prefix, literals are converted to their C equivalents and
|
|
symbols are output as-is (you're responsible for making sure they are
|
|
valid C identifiers). Indentation is handled automatically.
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#t</span> (<span class=variable>c-if</span> <span class=number>1</span> <span class=number>2</span> <span class=number>3</span>))</code>
|
|
<p>
|
|
|
|
outputs
|
|
<p>
|
|
|
|
<pre>
|
|
if (1) {
|
|
2;
|
|
} else {
|
|
3;
|
|
}
|
|
</pre>
|
|
<p>
|
|
|
|
In addition, the formatter knows when you're in an expression and
|
|
when you're in a statement, and behaves accordingly, so that
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#t</span> (<span class=variable>c-if</span> (<span class=variable>c-if</span> <span class=number>1</span> <span class=number>2</span> <span class=number>3</span>) <span class=number>4</span> <span class=number>5</span>))</code>
|
|
<p>
|
|
|
|
outputs
|
|
<p>
|
|
|
|
<pre>
|
|
if (1 ? 2 : 3) {
|
|
4;
|
|
} else {
|
|
5;
|
|
}
|
|
</pre>
|
|
<p>
|
|
|
|
Similary, <code class=scheme><span class=variable>c-begin</span></code>, used for sequencing, will separate with
|
|
semi-colons in a statement and commas in an expression.
|
|
<p>
|
|
|
|
Moreover, we also keep track of the final expression in a function
|
|
and insert returns for you:
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#t</span> (<span class=variable>c-fun</span> '<span class=variable>int</span> '<span class=variable>foo</span> '() (<span class=variable>c-if</span> (<span class=variable>c-if</span> <span class=number>1</span> <span class=number>2</span> <span class=number>3</span>) <span class=number>4</span> <span class=number>5</span>)))</code>
|
|
<p>
|
|
|
|
outputs
|
|
<p>
|
|
|
|
<pre>
|
|
int foo () {
|
|
if (1 ? 2 : 3) {
|
|
return 4;
|
|
} else {
|
|
return 5;
|
|
}
|
|
}
|
|
</pre>
|
|
<p>
|
|
|
|
although it knows that void functions don't return.
|
|
<p>
|
|
|
|
Switch statements insert breaks by default if they don't return:
|
|
<p>
|
|
|
|
<pre class=scheme>
|
|
(<span class=variable>fmt</span> <span class=boolean>#t</span> (<span class=variable>c-switch</span> '<span class=variable>y</span>
|
|
(<span class=variable>c-case</span> <span class=number>1</span> (<span class=variable>c+=</span> '<span class=variable>x</span> <span class=number>1</span>))
|
|
(<span class=variable>c-default</span> (<span class=variable>c+=</span> '<span class=variable>x</span> <span class=number>2</span>))))
|
|
</pre>
|
|
<p>
|
|
|
|
<pre>
|
|
switch (y) {
|
|
case 1:
|
|
x += 1;
|
|
break;
|
|
default:
|
|
x += 2;
|
|
break;
|
|
}
|
|
</pre>
|
|
<p>
|
|
|
|
though you can explicitly fallthrough if you want:
|
|
<p>
|
|
|
|
<pre class=scheme>
|
|
(<span class=variable>fmt</span> <span class=boolean>#t</span> (<span class=variable>c-switch</span> '<span class=variable>y</span>
|
|
(<span class=variable>c-case/fallthrough</span> <span class=number>1</span> (<span class=variable>c+=</span> '<span class=variable>x</span> <span class=number>1</span>))
|
|
(<span class=variable>c-default</span> (<span class=variable>c+=</span> '<span class=variable>x</span> <span class=number>2</span>))))
|
|
</pre>
|
|
<p>
|
|
|
|
<pre>
|
|
switch (y) {
|
|
case 1:
|
|
x += 1;
|
|
default:
|
|
x += 2;
|
|
break;
|
|
}
|
|
</pre>
|
|
<p>
|
|
|
|
Operators are available with just a "c" prefix, e.g. c+, c-, c*, c/,
|
|
etc. <code class=scheme><span class=variable>c++</span></code> is a prefix operator, <code class=scheme><span class=variable>c++/post</span></code> is postfix. ||, | and
|
|
|= are written as <code class=scheme><span class=variable>c-or</span></code>, <code class=scheme><span class=variable>c-bit-or</span></code> and <code class=scheme><span class=variable>c-bit-or=</span></code> respectively.
|
|
<p>
|
|
|
|
Function applications are written with <code class=scheme><span class=variable>c-apply</span></code>. Other control
|
|
structures such as <code class=scheme><span class=variable>c-for</span></code> and <code class=scheme><span class=variable>c-while</span></code> work as expected. The full
|
|
list is in the procedure index below.
|
|
<p>
|
|
|
|
When a C formatter encounters an object it doesn't know how to write
|
|
(including lists and records), it outputs them according to the
|
|
format state's current <code class=scheme>'<span class=variable>gen</span></code> variable. This allows you to specify
|
|
generators for your own types, e.g. if you are using your own AST
|
|
records in a compiler.
|
|
<p>
|
|
|
|
If the <code class=scheme>'<span class=variable>gen</span></code> variable isn't set it defaults to the <code class=scheme><span class=variable>c-expr/sexp</span></code>
|
|
procedure, which formats an s-expression as if it were C code. Thus
|
|
instead of <code class=scheme><span class=variable>c-apply</span></code> you can just use a list. The full API is
|
|
available via normal s-expressions - formatters that aren't keywords
|
|
in C are prefixed with a % or otherwise made invalid C identifiers so
|
|
that they can't be confused with function application.
|
|
<p>
|
|
|
|
<a name="SECTION_6.2"><h2>6.2 C Preprocessor Formatting</h2>
|
|
|
|
C preprocessor formatters also properly handle their surrounding
|
|
context, so you can safely intermix them in the normal flow of C
|
|
code.
|
|
<p>
|
|
|
|
<pre class=scheme>
|
|
(<span class=variable>fmt</span> <span class=boolean>#t</span> (<span class=variable>c-switch</span> '<span class=variable>y</span>
|
|
(<span class=variable>c-case</span> <span class=number>1</span> (<span class=variable>c=</span> '<span class=variable>x</span> <span class=number>1</span>))
|
|
(<span class=variable>cpp-ifdef</span> '<span class=variable>H_TWO</span> (<span class=variable>c-case</span> <span class=number>2</span> (<span class=variable>c=</span> '<span class=variable>x</span> <span class=number>4</span>)))
|
|
(<span class=variable>c-default</span> (<span class=variable>c=</span> '<span class=variable>x</span> <span class=number>5</span>))))
|
|
</pre>
|
|
<p>
|
|
|
|
<pre>
|
|
switch (y) {
|
|
case 1:
|
|
x = 1;
|
|
break;
|
|
|
|
#ifdef H_TWO
|
|
case 2:
|
|
x = 4;
|
|
break;
|
|
#endif /* H_TWO */
|
|
default:
|
|
x = 5;
|
|
break;
|
|
}
|
|
</pre>
|
|
<p>
|
|
|
|
Macros can be handled with <code class=scheme><span class=variable>cpp-define</span></code>, which knows to wrap
|
|
individual variable references in parenthesis:
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#t</span> (<span class=variable>cpp-define</span> '(<span class=variable>min</span> <span class=variable>x</span> <span class=variable>y</span>) (<span class=variable>c-if</span> (<span class=variable>c<</span> '<span class=variable>x</span> '<span class=variable>y</span>) '<span class=variable>x</span> '<span class=variable>y</span>)))</code>
|
|
<p>
|
|
|
|
<pre>
|
|
#define min(x, y) (((x) < (y)) ? (x) : (y))
|
|
</pre>
|
|
<p>
|
|
|
|
As with all C formatters, the CPP output is pretty printed as
|
|
needed, and if it wraps over several lines the lines are terminated
|
|
with a backslash.
|
|
<p>
|
|
|
|
To write a C header file that is included at most once, you can wrap
|
|
the entire body in <code class=scheme><span class=variable>cpp-wrap-header</span></code>:
|
|
<p>
|
|
|
|
<pre class=scheme>
|
|
(<span class=variable>fmt</span> <span class=boolean>#t</span> (<span class=variable>cpp-wrap-header</span> <span class=string>"FOO_H"</span>
|
|
(<span class=variable>c-extern</span> (<span class=variable>c-prototype</span> '<span class=variable>int</span> '<span class=variable>foo</span> '()))))
|
|
</pre>
|
|
<p>
|
|
|
|
<pre>
|
|
#ifndef FOO_H
|
|
#define FOO_H
|
|
|
|
extern int foo ();
|
|
|
|
#endif /* ! FOO_H */
|
|
</pre>
|
|
<p>
|
|
|
|
<a name="SECTION_6.3"><h2>6.3 Customizing C Style</h2>
|
|
|
|
The output uses a simplified K&R style with 4 spaces for indentation
|
|
by default. The following state variables let you override the
|
|
style:
|
|
<p>
|
|
|
|
<h3>'indent-space</h3>
|
|
|
|
how many spaces to indent bodies, default <code class=scheme><span class=number>4</span></code>
|
|
<p>
|
|
|
|
<h3>'switch-indent-space</h3>
|
|
|
|
how many spaces to indent switch clauses, also defaults to <code class=scheme><span class=number>4</span></code>
|
|
<p>
|
|
|
|
<h3>'newline-before-brace?</h3>
|
|
|
|
insert a newline before an open brace (non-K&R), defaults to <code class=scheme><span class=boolean>#f</span></code>
|
|
<p>
|
|
|
|
<h3>'braceless-bodies?</h3>
|
|
|
|
omit braces when we can prove they aren't needed
|
|
<p>
|
|
|
|
<h3>'non-spaced-ops?</h3>
|
|
|
|
omit spaces between operators and operands for groups of variables and
|
|
literals (e.g. "a+b+3" instead of "a + b + 3"}
|
|
<p>
|
|
|
|
<h3>'no-wrap?</h3>
|
|
|
|
Don't wrap function calls and long operator groups over mulitple
|
|
lines. Functions and control structures will still use multiple
|
|
lines.
|
|
<p>
|
|
|
|
The C formatters also respect the <code class=scheme>'<span class=variable>radix</span></code> and <code class=scheme>'<span class=variable>precision</span></code> settings.
|
|
<p>
|
|
|
|
<a name="SECTION_6.4"><h2>6.4 C Formatter Index</h2>
|
|
|
|
<h3>(c-if <condition> <pass> [<fail> [<condition2> <pass2> ...]])</h3>
|
|
|
|
Print a chain of if/else conditions. Use a final condition of <code class=scheme>'<span class=keyword>else</span></code>
|
|
for a final else clause.
|
|
<p>
|
|
|
|
<h3>(c-for <init> <condition> <update> <body> ...)</h3>
|
|
|
|
<h3>(c-while <condition> <body> ...)</h3>
|
|
|
|
Basic loop constructs.
|
|
<p>
|
|
|
|
<h3>(c-fun <type> <name> <params> <body> ...)</h3>
|
|
|
|
<h3>(c-prototype <type> <name> <params>)</h3>
|
|
|
|
Output a function or function prototype. The parameters should be a
|
|
list 2-element lists of the form <code class=scheme>(<span class=variable><param-type></span> <span class=variable><param-name></span>)</code>,
|
|
which are output with DSP. A parameter can be abbreviated as just the
|
|
symbol name, or <code class=scheme><span class=boolean>#f</span></code> can be passed as the type, in which case the
|
|
<code class=scheme>'<span class=variable>default-type</span></code> state variable is used. The parameters may be a
|
|
dotted list, in which case ellipses for a C variadic are inserted -
|
|
the actual name of the dotted value is ignored.
|
|
<p>
|
|
|
|
Types are just typically just symbols, or lists of symbols such as
|
|
<code class=scheme>'(<span class=variable>const</span> <span class=variable>char</span>)</code>. A complete description is given below in section
|
|
<a href="#SECTION_6.6">6.6</a>.
|
|
<p>
|
|
|
|
These can also accessed as %fun and %prototype at the head of a list.
|
|
<p>
|
|
|
|
<h3>(c-var <type> <name> [<init-value>])</h3>
|
|
|
|
Declares and optionally initializes a variable. Also accessed as %var
|
|
at the head of a list.
|
|
<p>
|
|
|
|
<h3>(c-begin <expr> ...)</h3>
|
|
|
|
Outputs each of the <expr>s, separated by semi-colons if in a
|
|
statement or commas if in an expression.
|
|
<p>
|
|
|
|
<h3>(c-switch <clause> ...)</h3>
|
|
|
|
<h3>(c-case <values> <body> ...)</h3>
|
|
|
|
<h3>(c-case/fallthrough <values> <body> ...)</h3>
|
|
|
|
<h3>(c-default <body> ...)</h3>
|
|
|
|
Switch statements. In addition to using the clause formatters,
|
|
clauses inside a switch may be handled with a Scheme CASE-like list,
|
|
with the car a list of case values and the cdr the body.
|
|
<p>
|
|
|
|
<h3>(c-label <name>)</h3>
|
|
|
|
<h3>(c-goto <name>)</h3>
|
|
|
|
<h3>(c-return [<result>])</h3>
|
|
|
|
<h3>c-break</h3>
|
|
|
|
<h3>c-continue</h3>
|
|
|
|
Manual labels and jumps. Labels can also be accessed as a list
|
|
beginning with a colon, e.g. <code class=scheme>'(<span class=constant>:</span> <span class=variable>label1</span>)</code>.
|
|
<p>
|
|
|
|
<h3>(c-const <expr>)</h3>
|
|
|
|
<h3>(c-static <expr>)</h3>
|
|
|
|
<h3>(c-volatile <expr>)</h3>
|
|
|
|
<h3>(c-restrict <expr>)</h3>
|
|
|
|
<h3>(c-register <expr>)</h3>
|
|
|
|
<h3>(c-auto <expr>)</h3>
|
|
|
|
<h3>(c-inline <expr>)</h3>
|
|
|
|
<h3>(c-extern <expr>)</h3>
|
|
|
|
Declaration modifiers. May be nested.
|
|
<p>
|
|
|
|
<h3>(c-extern/C <body> ...)</h3>
|
|
|
|
Wraps body in an extern "C" { ... } for use with C++.
|
|
<p>
|
|
|
|
<h3>(c-cast <type> <expr>)</h3>
|
|
|
|
Casts an expression to a type. Also %cast at the head of a list.
|
|
<p>
|
|
|
|
<h3>(c-typedef <type> <new-name> ...)</h3>
|
|
|
|
Creates a new type definition with one or more names.
|
|
<p>
|
|
|
|
<h3>(c-struct [<name>] <field-list> [<attributes>])</h3>
|
|
|
|
<h3>(c-union [<name>] <field-list> [<attributes>])</h3>
|
|
|
|
<h3>(c-class [<name>] <field-list> [<attributes>])</h3>
|
|
|
|
<h3>(c-attribute <values> ...)</h3>
|
|
|
|
Composite type constructors. Attributes may be accessed as
|
|
%attribute at the head of a list.
|
|
<p>
|
|
|
|
<pre class=scheme>
|
|
(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>c-struct</span> '<span class=variable>employee</span>
|
|
'((<span class=variable>short</span> <span class=variable>age</span>)
|
|
((<span class=variable>char</span> <span class=global>*</span>) <span class=variable>name</span>)
|
|
((<span class=variable>struct</span> (<span class=variable>year</span> <span class=variable>month</span> <span class=variable>day</span>)) <span class=variable>dob</span>))
|
|
(<span class=variable>c-attribute</span> '<span class=variable>packed</span>)))
|
|
</pre>
|
|
<p>
|
|
|
|
<pre>
|
|
struct employee {
|
|
short age;
|
|
char* name;
|
|
struct {
|
|
int year;
|
|
int month;
|
|
int day;
|
|
} dob;
|
|
} __attribute__ ((packed));
|
|
</pre>
|
|
<p>
|
|
|
|
<h3>(c-enum [<name>] <enum-list>)</h3>
|
|
|
|
Enumerated types. <code class=scheme><span class=variable><enum-list></span></code> may be strings, symbols, or lists of
|
|
string or symbol followed by the enum's value.
|
|
<p>
|
|
|
|
<h3>(c-comment <formatter> ...)</h3>
|
|
|
|
Outputs the <code class=scheme><span class=variable><formatter></span></code>s wrapped in C's /* ... */ comment. Properly
|
|
escapes nested comments inside in an Emacs-friendly style.
|
|
<p>
|
|
|
|
<a name="SECTION_6.5"><h2>6.5 C Preprocessor Formatter Index</h2>
|
|
|
|
<h3>(cpp-include <file>)</h3>
|
|
|
|
If file is a string, outputs in it "quotes", otherwise (as a symbol
|
|
or arbitrary formatter) it outputs it in brackets.
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>cpp-include</span> '<span class=variable>stdio.h</span>))</code>
|
|
<p>
|
|
|
|
<code class=scheme><span class=keyword>=></span> <span class=string>"#include <stdio.h>n"</span></code>
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#f</span> (<span class=variable>cpp-include</span> <span class=string>"config.h"</span>))</code>
|
|
<p>
|
|
|
|
<code class=scheme><span class=keyword>=></span> <span class=string>"#include "config.h"n"</span></code>
|
|
<p>
|
|
|
|
<h3>(cpp-define <macro> [<value>])</h3>
|
|
|
|
Defines a preprocessor macro, which may be just a name or a list of
|
|
name and parameters. Properly wraps the value in parenthesis and
|
|
escapes newlines. A dotted parameter list will use the C99 variadic
|
|
macro syntax, and will also substitute any references to the dotted
|
|
name with <code>__VA_ARGS__</code>:
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#t</span> (<span class=variable>cpp-define</span> '(<span class=variable>eprintf</span> . <span class=variable>args</span>) '(<span class=variable>fprintf</span> <span class=variable>stderr</span> <span class=variable>args</span>)))</code>
|
|
<p>
|
|
|
|
<pre>
|
|
#define eprintf(...) (fprintf(stderr, __VA_ARGS__))
|
|
</pre>
|
|
<p>
|
|
|
|
<h3>(cpp-if <condition> <pass> [<fail> ...])</h3>
|
|
|
|
<h3>(cpp-ifdef <condition> <pass> [<fail> ...])</h3>
|
|
|
|
<h3>(cpp-ifndef <condition> <pass> [<fail> ...])</h3>
|
|
|
|
<h3>(cpp-elif <condition> <pass> [<fail> ...])</h3>
|
|
|
|
<h3>(cpp-else <body> ...)</h3>
|
|
|
|
Conditional compilation.
|
|
<p>
|
|
|
|
<h3>(cpp-line <num> [<file>])</h3>
|
|
|
|
Line number information.
|
|
<p>
|
|
|
|
<h3>(cpp-pragma <args> ...)</h3>
|
|
|
|
<h3>(cpp-error <args> ...)</h3>
|
|
|
|
<h3>(cpp-warning <args> ...)</h3>
|
|
|
|
Additional preprocessor directives.
|
|
<p>
|
|
|
|
<h3>(cpp-stringify <expr>)</h3>
|
|
|
|
Stringifies <code class=scheme><span class=variable><expr></span></code> by prefixing the # operator.
|
|
<p>
|
|
|
|
<h3>(cpp-sym-cat <args> ...)</h3>
|
|
|
|
Joins the <code class=scheme><span class=variable><args></span></code> into a single preprocessor token with the ##
|
|
operator.
|
|
<p>
|
|
|
|
<h3>(cpp-wrap-header <name> <body> ...)</h3>
|
|
|
|
Wrap an entire header to only be included once.
|
|
<p>
|
|
|
|
<h3>Operators:</h3>
|
|
|
|
<pre class=scheme>
|
|
<span class=variable>c++</span> <span class=variable>c--</span> <span class=variable>c+</span> <span class=variable>c-</span> <span class=variable>c*</span> <span class=variable>c/</span> <span class=variable>c%</span> <span class=variable>c&</span> <span class=variable>c^</span> <span class=variable>c~</span> <span class=variable>c!</span> <span class=variable>c&&</span> <span class=variable>c<<</span> <span class=variable>c>></span> <span class=variable>c==</span> <span class=variable>c!=</span>
|
|
<span class=variable>c<</span> <span class=variable>c></span> <span class=variable>c<=</span> <span class=variable>c>=</span> <span class=variable>c=</span> <span class=variable>c+=</span> <span class=variable>c-=</span> <span class=variable>c*=</span> <span class=variable>c/=</span> <span class=variable>c%=</span> <span class=variable>c&=</span> <span class=variable>c^=</span> <span class=variable>c<<=</span> <span class=variable>c>>=</span>
|
|
<span class=variable>c++/post</span> <span class=variable>c--/post</span> <span class=variable>c-or</span> <span class=variable>c-bit-or</span> <span class=variable>c-bit-or=</span>
|
|
</pre>
|
|
<p>
|
|
|
|
<a name="SECTION_6.6"><h2>6.6 C Types</h2>
|
|
|
|
|
|
<p>
|
|
|
|
Typically a type is just a symbol such as <code class=scheme>'<span class=variable>char</span></code> or <code class=scheme>'<span class=variable>int</span></code>. You
|
|
can wrap types with modifiers such as <code class=scheme><span class=variable>c-const</span></code>, but as a
|
|
convenience you can just use a list such as in <code class=scheme>'(<span class=variable>const</span> <span class=variable>unsignedchar</span> <span class=global>*</span>)</code>.
|
|
You can also nest these lists, so the previous example is
|
|
equivalent to <code class=scheme>'(<span class=global>*</span> (<span class=variable>const</span> (<span class=variable>unsigned</span> <span class=variable>char</span>)))</code>.
|
|
<p>
|
|
|
|
Pointers may be written as <code class=scheme>'(<span class=variable>%pointer</span> <span class=variable><type></span>)</code> for readability -
|
|
<code class=scheme><span class=variable>%pointer</span></code> is exactly equivalent to <code class=scheme><span class=global>*</span></code> in types.
|
|
<p>
|
|
|
|
Unamed structs, classes, unions and enums may be used directly as
|
|
types, using their respective keywords at the head of a list.
|
|
<p>
|
|
|
|
Two special types are the %array type and function pointer type. An
|
|
array is written:
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>%array</span> <span class=variable><type></span> [<span class=variable><size></span>])</code>
|
|
<p>
|
|
|
|
where <code class=scheme><span class=variable><type></span></code> is any other type (including another array or
|
|
function pointer), and <code class=scheme><span class=variable><size></span></code>, if given, will print the array
|
|
size. For example:
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>c-var</span> '(<span class=variable>%array</span> (<span class=variable>unsigned</span> <span class=variable>long</span>) <span class=variable>SIZE</span>) '<span class=variable>table</span> '<span class=constant>#</span>(<span class=number>1</span> <span class=number>2</span> <span class=number>3</span> <span class=number>4</span>))</code>
|
|
<p>
|
|
|
|
<pre>
|
|
unsigned long table[SIZE] = {1, 2, 3, 4};
|
|
</pre>
|
|
<p>
|
|
|
|
A function pointer is written:
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>%fun</span> <span class=variable><return-type></span> (<span class=variable><param-types></span> ...))</code>
|
|
<p>
|
|
|
|
For example:
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>c-typedef</span> '(<span class=variable>%fun</span> <span class=variable>double</span> (<span class=variable>double</span> <span class=variable>double</span> <span class=variable>int</span>)) '<span class=variable>f</span>)</code>
|
|
<p>
|
|
|
|
<pre>
|
|
typedef double (*f)(double, double, int);
|
|
</pre>
|
|
<p>
|
|
|
|
Wherever a type is expected but not given, the value of the
|
|
<code class=scheme>'<span class=variable>default-type</span></code> formatting state variable is used. By default this
|
|
is just <code class=scheme>'<span class=variable>int</span></code>.
|
|
<p>
|
|
|
|
Type declarations work uniformly for variables and parameters, as well
|
|
for casts and typedefs.
|
|
<p>
|
|
|
|
<a name="SECTION_6.7"><h2>6.7 C as S-Expressions</h2>
|
|
|
|
|
|
<p>
|
|
|
|
Rather than building formatting closures by hand, it can be more
|
|
convenient to just build a normal s-expression and ask for it to be
|
|
formatted as C code. This can be thought of as a simple Scheme->C
|
|
compiler without any runtime support.
|
|
<p>
|
|
|
|
In a s-expression, strings and characters are printed as C strings and
|
|
characters, booleans are printed as 0 or 1, symbols are displayed
|
|
as-is, and numbers are printed as C numbers (using the current
|
|
formatting radix if specified). Vectors are printed as
|
|
comma-separated lists wrapped in braces, which can be used for
|
|
initializing arrays or structs.
|
|
<p>
|
|
|
|
A list indicates a C expression or statement. Any of the existing C
|
|
keywords can be used to pretty-print the expression as described with
|
|
the c-keyword formatters above. Thus, the example above
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#t</span> (<span class=variable>c-if</span> (<span class=variable>c-if</span> <span class=number>1</span> <span class=number>2</span> <span class=number>3</span>) <span class=number>4</span> <span class=number>5</span>))</code>
|
|
<p>
|
|
|
|
could also be written
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#t</span> (<span class=variable>c-expr</span> '(<span class=keyword>if</span> (<span class=keyword>if</span> <span class=number>1</span> <span class=number>2</span> <span class=number>3</span>) <span class=number>4</span> <span class=number>5</span>)))</code>
|
|
<p>
|
|
|
|
C constructs that are dependent on the underlying syntax and have no
|
|
keyword are written with a % prefix (<code class=scheme><span class=variable>%fun</span></code>, <code class=scheme><span class=variable>%var</span></code>, <code class=scheme><span class=variable>%pointer</span></code>,
|
|
<code class=scheme><span class=variable>%array</span></code>, <code class=scheme><span class=variable>%cast</span></code>), including C preprocessor constructs
|
|
(<code class=scheme><span class=variable>%include</span></code>, <code class=scheme><span class=variable>%define</span></code>, <code class=scheme><span class=variable>%pragma</span></code>, <code class=scheme><span class=variable>%error</span></code>, <code class=scheme><span class=variable>%warning</span></code>,
|
|
<code class=scheme><span class=variable>%if</span></code>, <code class=scheme><span class=variable>%ifdef</span></code>, <code class=scheme><span class=variable>%ifndef</span></code>, <code class=scheme><span class=variable>%elif</span></code>). Labels are written as
|
|
<code class=scheme>(<span class=constant>:</span> <span class=variable><label-name></span>)</code>. You can write a sequence as <code class=scheme>(<span class=variable>%begin</span> <span class=variable><expr></span>
|
|
...)</code>.
|
|
<p>
|
|
|
|
For example, the following definition of the fibonacci sequence, which
|
|
apart from the return type of <code class=scheme><span class=boolean>#f</span></code> looks like a Lisp definition:
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt</span> <span class=boolean>#t</span> (<span class=variable>c-expr</span> '(<span class=variable>%fun</span> <span class=boolean>#f</span> <span class=variable>fib</span> (<span class=variable>n</span>)
|
|
(<span class=keyword>if</span> (<span class=variable><=</span> <span class=variable>n</span> <span class=number>1</span>)
|
|
<span class=number>1</span>
|
|
(<span class=variable>+</span> (<span class=variable>fib</span> (<span class=variable>-</span> <span class=variable>n</span> <span class=number>1</span>)) (<span class=variable>fib</span> (<span class=variable>-</span> <span class=variable>n</span> <span class=number>2</span>)))))))</code>
|
|
<p>
|
|
|
|
prints the working C definition:
|
|
<p>
|
|
|
|
<pre>
|
|
int fib (int n) {
|
|
if (n <= 1) {
|
|
return 1;
|
|
} else {
|
|
return fib((n - 1)) + fib((n - 2));
|
|
}
|
|
}
|
|
</pre>
|
|
<p>
|
|
|
|
<a name="SECTION_7"><h1>7 JavaScript Formatting</h1>
|
|
|
|
The experimental fmt-js library extends the fmt-c library with
|
|
functionality for formatting JavaScript code.
|
|
<p>
|
|
|
|
<h3>(js-expr x)</h3>
|
|
|
|
Formats a JavaScript expression similarly to <code class=scheme><span class=variable>c-expr</span></code>. Inside a
|
|
<code class=scheme><span class=variable>js-expr</span></code> formatter, you can use the normal <code class=scheme><span class=variable>c-</span></code> prefixed
|
|
formatters described in the previous section, and they will format
|
|
appropriately for JavaScript.
|
|
<p>
|
|
|
|
Currently expressions will all be terminated with a semi-colon, but
|
|
that will be made optional in a later release.
|
|
<p>
|
|
|
|
<h3>(js-function [<name>] (<params>) <body> ...)</h3>
|
|
|
|
Defines a function (anonymously if no name is provided).
|
|
<p>
|
|
|
|
<h3>(js-var <name> [<init-value>])</h3>
|
|
|
|
Declares a JavaScript variable, optionally with an initial value.
|
|
<p>
|
|
|
|
<h3>(js-comment <formatter> ...)</h3>
|
|
|
|
Formats a comment prefixing lines with <code class=scheme><span class=string>"// "</span></code>.
|
|
<p>
|
|
|
|
<a name="SECTION_8"><h1>8 Formatting with Color</h1>
|
|
|
|
The fmt-color library provides the following utilities:
|
|
<p>
|
|
|
|
<pre class=scheme>
|
|
(<span class=variable>fmt-red</span> <span class=variable><formatter></span> ...)
|
|
(<span class=variable>fmt-blue</span> <span class=variable><formatter></span> ...)
|
|
(<span class=variable>fmt-green</span> <span class=variable><formatter></span> ...)
|
|
(<span class=variable>fmt-cyan</span> <span class=variable><formatter></span> ...)
|
|
(<span class=variable>fmt-yellow</span> <span class=variable><formatter></span> ...)
|
|
(<span class=variable>fmt-magenta</span> <span class=variable><formatter></span> ...)
|
|
(<span class=variable>fmt-white</span> <span class=variable><formatter></span> ...)
|
|
(<span class=variable>fmt-black</span> <span class=variable><formatter></span> ...)
|
|
(<span class=variable>fmt-bold</span> <span class=variable><formatter></span> ...)
|
|
(<span class=variable>fmt-underline</span> <span class=variable><formatter></span> ...)
|
|
</pre>
|
|
<p>
|
|
|
|
and more generally
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt-color</span> <span class=variable><color></span> <span class=variable><formatter></span> ...)</code>
|
|
<p>
|
|
|
|
where color can be a symbol name or <code class=scheme><span class=constant>#xRRGGBB</span></code> numeric value.
|
|
Outputs the formatters colored with ANSI escapes. In addition
|
|
<p>
|
|
|
|
<code class=scheme>(<span class=variable>fmt-in-html</span> <span class=variable><formatter></span> ...)</code>
|
|
<p>
|
|
|
|
can be used to mark the format state as being inside HTML, which the
|
|
above color formats will understand and output HTML <code class=scheme><span class=variable><span></span></code> tags with
|
|
the appropriate style colors, instead of ANSI escapes.
|
|
<p>
|
|
|
|
<a name="SECTION_9"><h1>9 Unicode</h1>
|
|
|
|
The fmt-unicode library provides the <code class=scheme><span class=variable>fmt-unicode</span></code> formatter, which
|
|
just takes a list of formatters and overrides the string-length for
|
|
padding and trimming, such that Unicode double or full width
|
|
characters are considered 2 characters wide (as they typically are in
|
|
fixed-width terminals), while treating combining and non-spacing
|
|
characters as 0 characters wide.
|
|
<p>
|
|
|
|
It also recognizes and ignores ANSI escapes, in particular useful if
|
|
you want to combine this with the fmt-color utilities.
|
|
<p>
|
|
|
|
<a name="SECTION_10"><h1>10 Optimizing</h1>
|
|
|
|
The library is designed for scalability and flexibility, not speed,
|
|
and I'm not going to think about any fine tuning until it's more
|
|
stabilised. One aspect of the design, however, was influenced for the
|
|
sake of future optimizations, which is that none of the default format
|
|
variables are initialized by global parameters, which leaves room for
|
|
inlining and subsequent simplification of format calls.
|
|
<p>
|
|
|
|
If you don't have an aggressively optimizing compiler, you can easily
|
|
achieve large speedups on common cases with CL-style compiler macros.
|
|
<p>
|
|
|
|
<a name="SECTION_11"><h1>11 Common Lisp Format Cheat Sheet</h1>
|
|
|
|
A quick reference for those of you switching over from Common Lisp's
|
|
format.
|
|
<p>
|
|
|
|
<table>
|
|
<tr><td><strong>format</strong> </td><td> <strong>fmt</strong></td></tr>
|
|
<tr><td>~a </td><td> <code class=scheme><span class=variable>dsp</span></code></td></tr>
|
|
<tr><td>~c </td><td> <code class=scheme><span class=variable>dsp</span></code></td></tr>
|
|
<tr><td>~s </td><td> <code class=scheme><span class=variable>wrt/unshared</span></code></td></tr>
|
|
<tr><td>~w </td><td> <code class=scheme><span class=variable>wrt</span></code></td></tr>
|
|
<tr><td>~y </td><td> <code class=scheme><span class=variable>pretty</span></code></td></tr>
|
|
<tr><td>~x </td><td> <code class=scheme>(<span class=variable>radix</span> <span class=number>16</span> ...)</code> or <code class=scheme>(<span class=variable>num</span> <span class=variable><n></span> <span class=number>16</span>)</code></td></tr>
|
|
<tr><td>~o </td><td> <code class=scheme>(<span class=variable>radix</span> <span class=number>8</span> ...)</code> or <code class=scheme>(<span class=variable>num</span> <span class=variable><n></span> <span class=number>8</span>)</code></td></tr>
|
|
<tr><td>~b </td><td> <code class=scheme>(<span class=variable>radix</span> <span class=number>2</span> ...)</code> or <code class=scheme>(<span class=variable>num</span> <span class=variable><n></span> <span class=number>2</span>)</code></td></tr>
|
|
<tr><td>~f </td><td> <code class=scheme>(<span class=variable>fix</span> <span class=variable><digits></span> ...)</code> or <code class=scheme>(<span class=variable>num</span> <span class=variable><n></span> <span class=variable><radix></span> <span class=variable><digits></span>)</code></td></tr>
|
|
<tr><td>~% </td><td> <code class=scheme><span class=variable>nl</span></code></td></tr>
|
|
<tr><td>~& </td><td> <code class=scheme><span class=variable>fl</span></code></td></tr>
|
|
<tr><td>~[...~] </td><td> normal <code class=scheme><span class=keyword>if</span></code> or <code class=scheme><span class=variable>fmt-if</span></code> (delayed test)</td></tr>
|
|
<tr><td>~{...~} </td><td> <code class=scheme>(<span class=variable>fmt-join</span> ... <span class=variable><list></span> [<span class=variable><sep></span>])</code></td></tr>
|
|
</table>
|
|
<p>
|
|
|
|
<a name="SECTION_12"><h1>12 References</h1>
|
|
|
|
<a name="BIBITEM_1">[1] R. Kelsey, W. Clinger, J. Rees (eds.)
|
|
<a href="http://www.schemers.org/Documents/Standards/R5RS/">Revised^5 Report on the Algorithmic Language Scheme</a>
|
|
<p>
|
|
|
|
<a name="BIBITEM_2">[2] Guy L. Steele Jr. (editor)
|
|
<a href="http://www.harlequin.com/education/books/HyperSpec/">Common Lisp Hyperspec</a>
|
|
<p>
|
|
|
|
<a name="BIBITEM_3">[3] Scott G. Miller
|
|
<a href="http://srfi.schemers.org/srfi-28/">SRFI-28 Basic Format Strings</a>
|
|
<p>
|
|
|
|
<a name="BIBITEM_4">[4] Ken Dickey
|
|
<a href="http://srfi.schemers.org/srfi-48/">SRFI-48 Intermediate Format Strings</a>
|
|
<p>
|
|
|
|
<a name="BIBITEM_5">[5] Ray Dillinger
|
|
<a href="http://srfi.schemers.org/srfi-38/">SRFI-38 External Representation for Data With Shared Structure</a>
|
|
<p>
|
|
|
|
<a name="BIBITEM_6">[6] Damian Conway
|
|
<a href="http://www.perl.com/lpt/a/819">Perl6 Exegesis 7 - formatting</a>
|
|
<p>
|
|
|
|
<br /><br /><br /><br />
|
|
<!-- page created by Mistie, http://www.cs.rice.edu/~dorai/mistie/ -->
|
|
</body></html>
|