Generating docs
bitterasm doc turns a module’s doc comments
into reference pages, and checks the examples in them. The
std reference is built by this command,
exactly as your own modules would be.
Syntax
bitterasm doc <paths>... [-o <dir>] # write pages (default: ./doc)
bitterasm doc <paths>... --summary SUMMARY.md # and list them in an mdBook
bitterasm doc <paths>... --test # compile the examples in doc comments
bitterasm doc <paths>... -o <dir> --check # fail if <dir> is out of date
Each path is a .basm file or a directory to search.
Where pages go
The pages follow the modules’ folders. The folder every module shares is
left off, so documenting myarch writes:
doc/
index.md # myarch: what's in it, each with its summary
util.md # myarch.util
x86/
index.md # myarch.x86's contents
native.md # myarch.x86.native
Each page’s title is the module’s own name, with the path to it underneath:
myarch › x86 › native, linking back to each folder. A module with a
folder of the same name next to it (x86.basm and x86/) becomes that
folder’s index.md, followed by the folder’s contents.
Adding the pages to an mdBook
mdBook only shows pages its SUMMARY.md lists. Put two marker lines under
the entry the pages belong to:
- [Reference](reference/index.md)
<!-- bitterasm doc: begin -->
<!-- bitterasm doc: end -->
and pass --summary. bitterasm doc replaces whatever is between the
markers with the pages, nested by folder and indented like the markers:
bitterasm doc myarch -o book/src/reference --summary book/src/SUMMARY.md
What goes on a page
Almost everything on a page comes from the code. Doc comments only add the prose.
- Macros, one section per name, with a row for each overload: how it’s
written, its parameters, and what it returns (
-> T) or emits (| emits T). - Types: structs with their
pubfields, enums with their variants, and type aliases. - Constants and
publabels.
The syntax column shows how a macro is written in that module. Suppose a module declares an instruction and two dialects re-export it:
## Adds two registers.
pub macro add(rd: int, rs1: int, rs2: int) {
@emit rd + rs1 + rs2
}
pub from .impl import *
pub from .impl import *
syntax add(rd, rs1, rs2) = { $rd$ = $rs1$ + $rs2$ }
The page for native shows add rd, rs1, rs2, and the page for c_like
shows rd = rs1 + rs2. Both work:
from .c_like import *
const x = 1
x = 2 + 3
6
A module’s page includes everything it re-exports with pub from.
Re-exported macros are listed in full, since a dialect may spell them
differently, with a column saying which module declares each overload.
Re-exported types and constants read the same everywhere, so they’re
listed by name with a link to their own module’s page.
When a name has several overloads, each row shows the first paragraph of that overload’s doc, and any longer doc appears in full below the table.
Testing examples
--test compiles every example in the doc comments of the given modules,
following the same rules as this book’s examples (see
Writing the docs). A fence
with no language is BitterASM, so an instruction’s encoding can be checked
right where it’s documented:
## Returns from the current function.
##
## ```
## from myarch.native import *
##
## ret
## ```
##
## ```bytes
## c3
## ```
pub macro ret() | emits Byte { ... }
Examples are compiled from the current directory, so they import your
modules the way a program would. Checking bytes needs bitter, found
next to bitterasm or on PATH. A failure names the example’s line:
error: myarch/native.basm:12: expected the bytes c3, but got c2
Keeping pages up to date
--check writes nothing, and fails if any page in the output directory
differs from what bitterasm doc would write, or belongs to a module that
no longer exists. With --summary, it also fails if the list in
SUMMARY.md is out of date. Run it in CI next to --test:
bitterasm doc myarch --test
bitterasm doc myarch -o book/src/reference --summary book/src/SUMMARY.md --check
Writing never deletes anything: a page left over from a module that’s gone is pointed out, for you to delete.
To make sure everything public is documented, turn on the missing_docs
lint, which is allowed by default. It reports each pub item without a
## comment, and a file without a #! block. A macro counts as
documented when any of its overloads in that file is.
bitterasm check myarch/native.basm -W missing_docs