llm
Download
359 lines 17.5 KiBMarkdownModified 2026-09-28 raw

NAME

tomo - The programming language of tomorrow.

SYNOPSIS

tomo [global flags] [command] [command flags] [args...]

Run a program: : tomo [run] program.tm [-- args...]

Build an executable: : tomo build [-o output] program.tm

Build a package: : tomo package [-o libname.a] [dir-or-file...]

DESCRIPTION

Tomo is a programming language that is statically typed, compiled, small, and garbage-collected, with concise syntax and built-in support for high-performance, low-overhead datastructures. It compiles by first outputting C code, which is then compiled using the Zig toolchain bundled with the Tomo installation.

A Tomo installation is relocatable: the tomo binary lives at prefix/bin/tomo@version, and it locates its libraries, headers, bundled toolchain, and man pages at startup relative to its own path (the prefix is the grandparent directory of the binary), so the whole tree can be moved or extracted into any prefix without rebuilding. The prefix is not fixed at build time; set $TOMO_PATH to override the automatically determined location (see ENVIRONMENT).

With no command, tomo file.tm runs the file (like tomo run), and bare tomo opens a scratch file in $EDITOR to edit and run (or compiles and runs a program piped in on standard input).

COMMANDS

Every command takes a --verbose/-v flag that turns on all build logs (the compile steps, up-to-date "Unchanged" notices, and the toolchain commands being run). Commands that print build progress by default (build, package, install) also take --quiet/-q to silence it. The run-style commands (tomo file.tm, run, eval) are silent by default: use tomo run -v file.tm to see the compiler's work.

run [--instrument] [--debug] file.tm [-- args...] : Compile and run the given program. Anything after -- is passed to the program as its own arguments. The command name is optional: tomo file.tm does the same thing. With --instrument, the program is compiled with profiling instrumentation and prints a breakdown of where its time went when it exits (see PROFILING). With --debug/-d, it runs under a debugger that stops on breakpoint() calls, runtime errors, and fatal signals (see DEBUGGING).

eval 'expr' : Evaluate a Tomo expression and print its result. The argument may be several statements separated by newlines or ; (for example tomo eval 'use random; random.int(1, 100)'); every statement that evaluates to something prints what it evaluated to, with syntax coloring when standard output is a terminal. The argument is ordinary Tomo source, so it can also declare variables and functions and use other modules.

build [-o output] [--install] [--prefix dir] [-y] [--instrument] [--debug] [--package-sources dir] [--skip-source] file.tm : Compile the given program to a standalone executable, placed as a sibling of the .tm file (or at -o output). With --package-sources dir, pinned packages are found by content digest in dir (a directory of package sources, like the packages/ directory of an extracted source archive) instead of being downloaded; run and test take the same flag. With --skip-source, the program's sources are not embedded in the executable, which makes it smaller but means tomo source cannot unpack it back into a buildable project. With --instrument, the executable is compiled with profiling instrumentation and prints a breakdown of where its time went when it exits (see PROFILING). With --debug/-d, it is compiled so a debugger can follow it (see DEBUGGING). With --install, the executable and its generated manpage are also copied into a prefix's bin/ and man/man1/, the installation prefix by default, or --prefix dir to choose another. Existing files at those destinations are overwritten only after confirmation, or immediately with --yes/-y; a warning is printed if the target bin/ is not on your $PATH. Remove installed programs again with tomo uninstall name.

transpile [--raw] [--instrument] [--debug] file.tm : Transpile the given file to C and print the generated header and source to standard output, each preceded by a // file: line. The output is formatted with clang-format and (when standard output is a terminal) syntax-highlighted with bat, whichever of the two is installed; --raw prints the raw generated code instead. The generated .h/.c files are also written into the file's .tomo/ directory.

parse file.tm... : Print the parse tree of the given files as S-expressions.

format [-i] file.tm... : Autoformat the given files and print them to standard output, or rewrite them in place with --in-place/-i. Also available as fmt.

package [-o libname.a] [dir-or-file...] : Build packages into static archives. With no arguments, the current directory is built as a package: every .tm file not starting with an underscore (or dot or digit) is compiled and archived into package.a. Directory arguments are each built the same way; .tm file arguments are compiled into a single archive. -o sets the archive path (single package only).

uninstall [-y] [name-or-path...] : With one or more arguments, uninstall those installed programs. Each argument is either a bare name (looked up in the prefix's bin/) or a path to a binary. A binary is removed only if it is a Tomo program (it carries Tomo's embedded build info), and its Tomo-generated manpage in man/man1/ is removed along with it. Files Tomo did not create are left untouched, and a missing binary or manpage is only a warning. Install programs with tomo build --install.

: With no arguments, uninstall this whole Tomo installation: remove this version's files from the installation prefix, along with its per-user state, cross-compilation target packs, and any bundled toolchains no remaining installation shares. If other Tomo versions remain in the same prefix, the tomo and man page symlinks are repointed to the newest one; otherwise they are removed too. If no tomo remains anywhere on $PATH afterwards, the cache (~/.cache/tomo: package downloads and the bundled Zig toolchain's compile cache) is also cleared. Asks for confirmation unless --yes/-y is given.

vendor [-e|-u] package... : Copy the named packages' digest-verified source archives into the current project's vendor/ directory and update ./packages.ini to use the vendored copies as the primary sources (keeping the digest pins and demoting the previous sources to fallbacks). With --editable/-e, extract each package's sources into vendor/<name>/ and drop its digest pin, so the vendored copy can be edited freely. With --unvendor/-u, undo vendoring: restore each package's ./packages.ini entry to its first non-vendored fallback source (or the compiler's default pin), re-install the package into the project's package store (re-pinning the digest if editable vendoring dropped it), and delete the vendored copy.

version : Print the compiler version and exit (with --verbose/-v: plus the git revision).

info binary... : Print the build info embedded in the given compiled files (executables or package archives).

source [-o dest] binary... : List the contents of the source archive embedded in each of the given compiled programs. With --output/-o dest, get the archive out instead (one binary at a time): a dest ending in .zip is written as a zip file of the archive itself, and any other dest is a directory to unpack into. The extracted directory is a self-contained project: src/ holds the program's sources, embedded files, and relatively-used C files, packages/ holds the sources of every used package by content digest, licenses/ holds the license texts, and a generated README.md and Makefile document and perform the rebuild (plain make, or tomo build --package-sources ./packages on the entry file), with no network access needed. Not every program carries an archive: tomo build --skip-source leaves it out, and so do the executables tomo run and tomo eval build, which are run once and discarded.

GLOBAL OPTIONS

Global options are valid anywhere on the command line, before or after the command name. Command-specific flags (like build's -o) are only valid after their command.

--help, -h : Print the usage (or a command's usage) and exit.

--optimization level, -O level : Set the optimization level.

--force-rebuild, -f : Force rebuilding/recompiling.

--source-mapping=, -m= <yes|no> : Toggle whether source mapping should be enabled or disabled.

--target platform : Cross-compile for another platform instead of this machine's. The target platform's libraries are installed on demand from its Tomo distribution archive. Cross-compiled executables get the platform as a filename suffix (e.g. foo.aarch64-macos) and cannot be run or installed on this machine. Valid platforms are: x86_64-linux, aarch64-linux, riscv64-linux, powerpc64le-linux, s390x-linux, x86_64-macos, aarch64-macos, x86_64-freebsd, aarch64-freebsd, x86_64-netbsd, aarch64-netbsd, x86_64-openbsd, and aarch64-openbsd.

--install-target : When using --target, download and install the target platform's libraries without asking for confirmation.

PROFILING

A program compiled with --instrument (tomo build --instrument file.tm, or tomo run --instrument file.tm) times every function, conversion, and lambda it defines, and prints a report to standard error when it exits: for each function that ran, the number of calls, the time spent inside it (with its callees' time subtracted), the time spent in it and everything it called, and the per-call average, sorted by the first of those. The report is printed even when the program exits early, fails, or crashes. Instrumented calls cost around 13ns each (two reads of the CPU's cycle counter), charged to the calling function, so --instrument is for finding where the time goes rather than for measuring absolute speed.

Setting FLAME_GRAPH to a path additionally writes the call tree there as an SVG flame graph: one box per frame, as wide as its share of the run and stacked on the frame that called it, each carrying its details in a hover tooltip.

The program's own arguments are left alone; the report is controlled by PROFILE, PROFILE_FILE, and FLAME_GRAPH (see ENVIRONMENT). See also docs/profiling.md.

DEBUGGING

tomo run --debug file.tm runs a program under gdb(1), with Tomo's debugger integration loaded into it. The program starts immediately and runs as it normally would; it stops when something stops it, whether a breakpoint() call in the source, a runtime error, a fatal signal, or an interrupt, and leaves you at a debugger prompt showing the Tomo function, the source around the line it stopped on, and the Tomo variables in scope. A program that finishes on its own leaves the debugger with its own exit status, exactly as tomo run would have.

Because Tomo's generated C carries #line directives back to the .tm file, gdb's own commands work in Tomo's terms: break file.tm:line, step, next, finish, continue, list, watch, and conditional breakpoints all behave as they would for a C program written in the .tm file. Function names are reported as Tomo names rather than the mangled C symbols they compile to.

Commands are added on top of gdb's own: tlocals lists the Tomo variables in scope, p var prints one of them, and tframe re-shows where the program is stopped. frame, up, and down report the frame they select the way a stop is reported: the Tomo name of the function, the source around the line, and the variables in scope. backtrace (and bt/where) is likewise replaced by one that prints the stack in Tomo's terms, helper(label="widgets", count=7), with argument values cut short; gdb's own backtrace remains available as info stack. These print values with Tomo's own formatter, the same output say() would produce with syntax coloring included, rather than the C structures they compile to. gdb's own print does the same for values whose C type belongs to exactly one Tomo type.

A Num is exact, so it prints exactly as 32768/3, pi, or 1/2 + sqrt(5)/2, and the debugger shows a rounded decimal beside it (32768/3 \[u2248] 10922.6666666667) for the ones no decimal expresses. set tomo-num-digits n sets how many fractional digits that carries, and 0 turns it off.

A Tomo value is formatted whole and the variables in scope are printed at every stop, so values are cut off to keep one large one from burying the screen, using gdb's own set print elements as the cutoff.

A Tomo variable x is _$x in the generated C, so a bare Tomo name typed at gdb finds either nothing or some unrelated C symbol of that name. p (which replaces gdb's alias for print) rewrites Tomo names to the C names they compile to; print and every other command are untouched and still take C names (a watchpoint on x is watch _$x), and anything p does not recognize is passed to print unchanged, so format letters and value history behave as they always did.

--debug makes two changes to how the program is compiled. It defaults to -O0 (an explicit -O still wins) so that the program a debugger sees is the one that was written, and it emits, beside every variable, the type information Tomo's formatter needs to print that variable, which is the only way a debugger can show what is inside a list, table, or optional, since those do not record their contents in their C type.

breakpoint() is a built-in that stops the program where it is called. Only a program compiled with --debug contains it at all: without that flag it compiles to nothing, so leaving one in the source costs a release build nothing.

Runtime errors stop in the debugger too. tomo run --debug sets TOMO_CORE_DUMP, which makes fail(), a failed assertion, or an out-of-range access raise SIGABRT after printing its usual report, instead of exiting, so the failing frame and its variables are still there to look at. SIGSEGV, SIGFPE, SIGILL, SIGBUS, and SIGSYS stop the same way; an interrupt (SIGINT) stops the program without killing it, so continue resumes.

--debug is also available on build, transpile, and test. A program built with it can be started under the debugger by hand by loading prefix/lib/tomo@version/tomo-gdb.py with gdb -x. See also docs/debugging.md.

ENVIRONMENT

TOMO_PATH : The installation prefix Tomo compiles and links against (its lib/, include/, libexec/, and man/ trees) and installs into. By default this is determined at runtime from the location of the running tomo binary (the grandparent of the resolved executable path), so an installation is relocatable. Set TOMO_PATH to override it, for example to point at a tree in an unusual location or one whose tomo binary has been copied away from its sibling directories.

TOMO_DIST_URL : Base URL for downloading distribution archives (used by --target and --install-target to fetch a target platform's libraries). Defaults to https://tomo.bruce-hill.com/dist.

EDITOR : The editor bare tomo opens the scratch file in. Defaults to vim.

NO_COLOR, COLOR : Set NO_COLOR to any non-empty value to disable colored output. Set COLOR to 1 to force it on; otherwise color is used only when standard output is a terminal.

TOMO_STACKTRACE, TOMO_PLAIN_ERRORS, TOMO_CORE_DUMP : Diagnostics for compiler and runtime errors: TOMO_STACKTRACE prints a stack trace on errors, TOMO_PLAIN_ERRORS disables the fancy source-quoting error formatting, and setting TOMO_CORE_DUMP to a truthy value makes a fatal error abort (dumping core) instead of exiting cleanly.

TOMO_TEST_FILTER, TOMO_TEST_TIMEOUT, TOMO_TEST_VERBOSE : Control tomo test runs: only run tests whose label contains TOMO_TEST_FILTER, cap each test at TOMO_TEST_TIMEOUT seconds, and print verbose output when TOMO_TEST_VERBOSE is set.

PROFILE, PROFILE_FILE, FLAME_GRAPH : Control the profile report of a program compiled with --instrument (see PROFILING). Setting PROFILE to 0 (or no/false) makes the program collect nothing and print nothing, so an instrumented binary can also be run as a normal one. PROFILE_FILE writes the table to that path instead of standard error (- means standard output). FLAME_GRAPH writes an SVG flame graph to that path as well as the table. All three are read by the compiled program, not by tomo.

TOMO_DEBUGGER : The debugger tomo run --debug launches. Defaults to gdb, found on $PATH; set this to use a different gdb build or a gdb-compatible debugger (see DEBUGGING).

ZIG_GLOBAL_CACHE_DIR : Where the bundled Zig toolchain keeps its global compile cache. If unset, Tomo points it at its own cache directory (under $XDG_CACHE_HOME/tomo) rather than Zig's default, so it never mingles with a separately-run Zig's cache; an explicit value is respected.

FILES

prefix/bin/tomo@version : The compiler binary, with a bin/tomo symlink to the newest coresident version. Programs installed with tomo build --install also land in prefix/bin/.

prefix/lib/tomo@version/, prefix/include/tomo@version/ : The Tomo standard library archive and headers this version links against.

prefix/lib/tomo@version/tomo-gdb.py : Tomo's debugger integration, loaded into gdb by tomo run --debug (see DEBUGGING).

prefix/man/man1/ : Man pages, including those installed for programs built with tomo build --install.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
% TOMO(1)
% Bruce Hill (*bruce@bruce-hill.com*)
% August 16, 2026

# NAME

tomo - The programming language of tomorrow.

# SYNOPSIS

`tomo` \[*global flags*\] \[*command*\] \[*command flags*\] \[*args...*\]

Run a program:
: `tomo` \[`run`\] *program.tm* \[`--` *args...*\]

Build an executable:
: `tomo` `build` \[`-o` *output*\] *program.tm*

Build a package:
: `tomo` `package` \[`-o` *libname.a*\] \[*dir-or-file...*\]

# DESCRIPTION

Tomo is a programming language that is statically typed, compiled, small, and
garbage-collected, with concise syntax and built-in support for
high-performance, low-overhead datastructures. It compiles by first outputting
C code, which is then compiled using the Zig toolchain bundled with the Tomo
installation.

A Tomo installation is relocatable: the `tomo` binary lives at
*prefix*`/bin/tomo@`*version*, and it locates its libraries, headers, bundled
toolchain, and man pages at startup relative to its own path (the *prefix* is
the grandparent directory of the binary), so the whole tree can be moved or
extracted into any prefix without rebuilding. The prefix is not fixed at build
time; set `$TOMO_PATH` to override the automatically determined location (see
**ENVIRONMENT**).

With no command, `tomo` *file.tm* runs the file (like `tomo run`), and bare
`tomo` opens a scratch file in `$EDITOR` to edit and run (or compiles and runs
a program piped in on standard input).

# COMMANDS

Every command takes a `--verbose`/`-v` flag that turns on all build logs (the
compile steps, up-to-date "Unchanged" notices, and the toolchain commands being
run). Commands that print build progress by default (`build`, `package`,
`install`) also take `--quiet`/`-q` to silence it. The run-style commands
(`tomo` *file.tm*, `run`, `eval`) are silent by default: use `tomo run -v`
*file.tm* to see the compiler's work.

`run` \[`--instrument`\] \[`--debug`\] *file.tm* \[`--` *args...*\]
: Compile and run the given program. Anything after `--` is passed to the
program as its own arguments. The command name is optional: `tomo` *file.tm*
does the same thing. With `--instrument`, the program is compiled with
profiling instrumentation and prints a breakdown of where its time went when
it exits (see **PROFILING**). With `--debug`/`-d`, it runs under a debugger
that stops on `breakpoint()` calls, runtime errors, and fatal signals (see
**DEBUGGING**).

`eval` *'expr'*
: Evaluate a Tomo expression and print its result. The argument may be several
statements separated by newlines or `;` (for example `tomo eval 'use random;
random.int(1, 100)'`); every statement that evaluates to something prints what
it evaluated to, with syntax coloring when standard output is a terminal. The
argument is ordinary Tomo source, so it can also declare variables and
functions and `use` other modules.

`build` \[`-o` *output*\] \[`--install`\] \[`--prefix` *dir*\] \[`-y`\]
\[`--instrument`\] \[`--debug`\] \[`--package-sources` *dir*\] \[`--skip-source`\]
*file.tm*
: Compile the given program to a standalone executable, placed as a sibling
of the `.tm` file (or at `-o` *output*). With `--package-sources` *dir*, pinned
packages are found by content digest in *dir* (a directory of package sources,
like the `packages/` directory of an extracted source archive) instead of
being downloaded; `run` and `test` take the same flag. With `--skip-source`,
the program's sources are not embedded in the executable, which makes it
smaller but means `tomo source` cannot unpack it back into a buildable
project. With `--instrument`, the executable
is compiled with profiling instrumentation and prints a breakdown of where its
time went when it exits (see **PROFILING**). With `--debug`/`-d`, it is compiled
so a debugger can follow it (see **DEBUGGING**). With `--install`, the executable and
its generated manpage are also copied into a prefix's `bin/` and `man/man1/`,
the installation prefix by default, or `--prefix` *dir* to choose another.
Existing files at those destinations are overwritten only after confirmation,
or immediately with `--yes`/`-y`; a warning is printed if the target `bin/` is
not on your `$PATH`. Remove installed programs again with `tomo uninstall`
*name*.

`transpile` \[`--raw`\] \[`--instrument`\] \[`--debug`\] *file.tm*
: Transpile the given file to C and print the generated header and source to
standard output, each preceded by a `// file:` line. The output is formatted
with `clang-format` and (when standard output is a terminal)
syntax-highlighted with `bat`, whichever of the two is installed; `--raw`
prints the raw generated code instead. The generated `.h`/`.c` files are also
written into the file's `.tomo/` directory.

`parse` *file.tm...*
: Print the parse tree of the given files as S-expressions.

`format` \[`-i`\] *file.tm...*
: Autoformat the given files and print them to standard output, or rewrite
them in place with `--in-place`/`-i`. Also available as `fmt`.

`package` \[`-o` *libname.a*\] \[*dir-or-file...*\]
: Build packages into static archives. With no arguments, the current
directory is built as a package: every `.tm` file not starting with an
underscore (or dot or digit) is compiled and archived into `package.a`.
Directory arguments are each built the same way; `.tm` file arguments are
compiled into a single archive. `-o` sets the archive path (single package
only).

`uninstall` \[`-y`\] \[*name-or-path...*\]
: With one or more arguments, uninstall those installed programs. Each
argument is either a bare *name* (looked up in the prefix's `bin/`) or a
path to a binary. A binary is removed only if it is a Tomo program (it
carries Tomo's embedded build info), and its Tomo-generated manpage in
`man/man1/` is removed along with it. Files Tomo did not create are left
untouched, and a missing binary or manpage is only a warning. Install
programs with `tomo build --install`.

: With no arguments, uninstall this whole Tomo installation: remove this
version's files from the installation prefix, along with its per-user state,
cross-compilation target packs, and any bundled toolchains no remaining
installation shares. If other Tomo versions remain in the same prefix, the
`tomo` and man page symlinks are repointed to the newest one; otherwise they
are removed too. If no `tomo` remains anywhere on `$PATH` afterwards, the
cache (`~/.cache/tomo`: package downloads and the bundled Zig toolchain's
compile cache) is also cleared. Asks for confirmation unless `--yes`/`-y` is
given.

`vendor` \[`-e`|`-u`\] *package...*
: Copy the named packages' digest-verified source archives into the current
project's `vendor/` directory and update `./packages.ini` to use the vendored
copies as the primary sources (keeping the digest pins and demoting the
previous sources to fallbacks). With `--editable`/`-e`, extract each package's
sources into `vendor/<name>/` and drop its digest pin, so the vendored copy
can be edited freely. With `--unvendor`/`-u`, undo vendoring: restore each
package's `./packages.ini` entry to its first non-vendored fallback source
(or the compiler's default pin), re-install the package into the project's
package store (re-pinning the digest if editable vendoring dropped it), and
delete the vendored copy.

`version`
: Print the compiler version and exit (with `--verbose`/`-v`: plus the git
revision).

`info` *binary...*
: Print the build info embedded in the given compiled files (executables or
package archives).

`source` \[`-o` *dest*\] *binary...*
: List the contents of the source archive embedded in each of the given
compiled programs. With `--output`/`-o` *dest*, get the archive out instead
(one binary at a time): a *dest* ending in `.zip` is written as a zip file of
the archive itself, and any other *dest* is a directory to unpack into. The
extracted directory is a self-contained project: `src/` holds the program's
sources, embedded files, and relatively-`use`d C files, `packages/` holds the
sources of every used package by content digest, `licenses/` holds the license
texts, and a generated `README.md` and `Makefile` document and perform the
rebuild (plain `make`, or `tomo build --package-sources ./packages` on the
entry file), with no network access needed. Not every program carries an
archive: `tomo build --skip-source` leaves it out, and so do the executables
`tomo run` and `tomo eval` build, which are run once and discarded.

# GLOBAL OPTIONS

Global options are valid anywhere on the command line, before or after the
command name. Command-specific flags (like `build`'s `-o`) are only valid
after their command.

`--help`, `-h`
: Print the usage (or a command's usage) and exit.

`--optimization` **level**, `-O` **level**
: Set the optimization level.

`--force-rebuild`, `-f`
: Force rebuilding/recompiling.

`--source-mapping=`, `-m=` **<yes|no>**
: Toggle whether source mapping should be enabled or disabled.

`--target` *platform*
: Cross-compile for another platform instead of this machine's. The target
platform's libraries are installed on demand from its Tomo distribution
archive. Cross-compiled executables get the platform as a filename suffix
(e.g. `foo.aarch64-macos`) and cannot be run or installed on this machine.
Valid platforms are: `x86_64-linux`, `aarch64-linux`, `riscv64-linux`,
`powerpc64le-linux`, `s390x-linux`, `x86_64-macos`, `aarch64-macos`,
`x86_64-freebsd`, `aarch64-freebsd`, `x86_64-netbsd`, `aarch64-netbsd`,
`x86_64-openbsd`, and `aarch64-openbsd`.

`--install-target`
: When using `--target`, download and install the target platform's libraries
without asking for confirmation.

# PROFILING

A program compiled with `--instrument` (`tomo build --instrument` *file.tm*,
or `tomo run --instrument` *file.tm*) times every function, conversion, and
lambda it defines, and prints a report to standard error when it exits: for
each function that ran, the number of calls, the time spent inside it (with
its callees' time subtracted), the time spent in it and everything it called,
and the per-call average, sorted by the first of those. The report is printed
even when the program exits early, fails, or crashes. Instrumented calls cost
around 13ns each (two reads of the CPU's cycle counter), charged to the calling
function, so `--instrument` is for finding where the time goes rather than for
measuring absolute speed.

Setting `FLAME_GRAPH` to a path additionally writes the call tree there as an
SVG flame graph: one box per frame, as wide as its share of the run and stacked
on the frame that called it, each carrying its details in a hover tooltip.

The program's own arguments are left alone; the report is controlled by
`PROFILE`, `PROFILE_FILE`, and `FLAME_GRAPH` (see **ENVIRONMENT**). See also
*docs/profiling.md*.

# DEBUGGING

`tomo run --debug` *file.tm* runs a program under `gdb`(1), with Tomo's
debugger integration loaded into it. The program starts immediately and runs
as it normally would; it stops when something stops it, whether a
`breakpoint()` call in the source, a runtime error, a fatal signal, or an
interrupt, and leaves
you at a debugger prompt showing the Tomo function, the source around the line
it stopped on, and the Tomo variables in scope. A program that finishes on its
own leaves the debugger with its own exit status, exactly as `tomo run` would
have.

Because Tomo's generated C carries `#line` directives back to the `.tm` file,
gdb's own commands work in Tomo's terms: `break` *file.tm*`:`*line*, `step`,
`next`, `finish`, `continue`, `list`, `watch`, and conditional breakpoints all
behave as they would for a C program written in the `.tm` file. Function names
are reported as Tomo names rather than the mangled C symbols they compile to.

Commands are added on top of gdb's own: `tlocals` lists the Tomo variables in
scope, `p` *var* prints one of them, and `tframe` re-shows where the program is
stopped. `frame`, `up`, and `down` report the frame they select the way a stop
is reported: the Tomo name of the function, the source around the line, and the
variables in scope. `backtrace` (and `bt`/`where`) is likewise replaced by one
that prints the stack in Tomo's terms, `helper(label="widgets", count=7)`,
with argument values cut short; gdb's own backtrace remains available as `info
stack`. These print values with Tomo's own formatter, the same output `say()`
would produce with syntax coloring included, rather than the C structures they
compile to. gdb's own `print` does the same for values whose C type belongs to
exactly one Tomo type.

A `Num` is exact, so it prints exactly as `32768/3`, `pi`, or
`1/2 + sqrt(5)/2`, and the debugger shows a rounded decimal beside it (`32768/3 \[u2248] 10922.6666666667`)
for the ones no decimal expresses. `set tomo-num-digits` *n* sets how many
fractional digits that carries, and `0` turns it off.

A Tomo value is formatted whole and the variables in scope are printed at every
stop, so values are cut off to keep one large one from
burying the screen, using gdb's own `set print elements` as the cutoff.

A Tomo variable *x* is `_$`*x* in the generated C, so a bare Tomo name typed at
gdb finds either nothing or some unrelated C symbol of that name. `p` (which
replaces gdb's alias for `print`) rewrites Tomo names to the C names
they compile to; `print` and every other command are untouched and still take C
names (a watchpoint on *x* is `watch _$`*x*), and anything `p` does not recognize is passed to `print` unchanged, so
format letters and value history behave as they always did.

`--debug` makes two changes to how the program is compiled. It defaults to
`-O0` (an explicit `-O` still wins) so that the program a debugger sees is the
one that was written, and it emits, beside every variable, the type information
Tomo's formatter needs to print that variable, which is the only way a
debugger can show what is inside a list, table, or optional, since those do not
record their contents in their C type.

`breakpoint()` is a built-in that stops the program where it is called. Only a
program compiled with `--debug` contains it at all: without that flag it
compiles to nothing, so leaving one in the source costs a release build
nothing.

Runtime errors stop in the debugger too. `tomo run --debug` sets
`TOMO_CORE_DUMP`, which makes `fail()`, a failed assertion, or an out-of-range
access raise `SIGABRT` after printing its usual report, instead of exiting, so
the failing frame and its variables are still there to look at. `SIGSEGV`,
`SIGFPE`, `SIGILL`, `SIGBUS`, and `SIGSYS` stop the same way; an interrupt
(`SIGINT`) stops the program without killing it, so `continue` resumes.

`--debug` is also available on `build`, `transpile`, and `test`. A program
built with it can be started under the debugger by hand by loading
*prefix*`/lib/tomo@`*version*`/tomo-gdb.py` with `gdb -x`. See also
*docs/debugging.md*.

# ENVIRONMENT

`TOMO_PATH`
: The installation prefix Tomo compiles and links against (its `lib/`,
`include/`, `libexec/`, and `man/` trees) and installs into. By default this
is determined at runtime from the location of the running `tomo` binary (the
grandparent of the resolved executable path), so an installation is
relocatable. Set `TOMO_PATH` to override it, for example to point at a tree in
an unusual location or one whose `tomo` binary has been copied away from its
sibling directories.

`TOMO_DIST_URL`
: Base URL for downloading distribution archives (used by `--target` and
`--install-target` to fetch a target platform's libraries). Defaults to
*https://tomo.bruce-hill.com/dist*.

`EDITOR`
: The editor bare `tomo` opens the scratch file in. Defaults to `vim`.

`NO_COLOR`, `COLOR`
: Set `NO_COLOR` to any non-empty value to disable colored output. Set `COLOR`
to `1` to force it on; otherwise color is used only when standard output is a
terminal.

`TOMO_STACKTRACE`, `TOMO_PLAIN_ERRORS`, `TOMO_CORE_DUMP`
: Diagnostics for compiler and runtime errors: `TOMO_STACKTRACE` prints a
stack trace on errors, `TOMO_PLAIN_ERRORS` disables the fancy source-quoting
error formatting, and setting `TOMO_CORE_DUMP` to a truthy value makes a fatal
error abort (dumping core) instead of exiting cleanly.

`TOMO_TEST_FILTER`, `TOMO_TEST_TIMEOUT`, `TOMO_TEST_VERBOSE`
: Control `tomo test` runs: only run tests whose label contains
`TOMO_TEST_FILTER`, cap each test at `TOMO_TEST_TIMEOUT` seconds, and print
verbose output when `TOMO_TEST_VERBOSE` is set.

`PROFILE`, `PROFILE_FILE`, `FLAME_GRAPH`
: Control the profile report of a program compiled with `--instrument` (see
**PROFILING**). Setting `PROFILE` to `0` (or `no`/`false`) makes the program
collect nothing and print nothing, so an instrumented binary can also be run
as a normal one. `PROFILE_FILE` writes the table to that path instead of
standard error (`-` means standard output). `FLAME_GRAPH` writes an SVG flame
graph to that path as well as the table. All three are read by the compiled
program, not by `tomo`.

`TOMO_DEBUGGER`
: The debugger `tomo run --debug` launches. Defaults to `gdb`, found on
`$PATH`; set this to use a different gdb build or a gdb-compatible debugger
(see **DEBUGGING**).

`ZIG_GLOBAL_CACHE_DIR`
: Where the bundled Zig toolchain keeps its global compile cache. If unset,
Tomo points it at its own cache directory (under `$XDG_CACHE_HOME/tomo`) rather
than Zig's default, so it never mingles with a separately-run Zig's cache; an
explicit value is respected.

# FILES

*prefix*`/bin/tomo@`*version*
: The compiler binary, with a `bin/tomo` symlink to the newest coresident
version. Programs installed with `tomo build --install` also land in
*prefix*`/bin/`.

*prefix*`/lib/tomo@`*version*`/`, *prefix*`/include/tomo@`*version*`/`
: The Tomo standard library archive and headers this version links against.

*prefix*`/lib/tomo@`*version*`/tomo-gdb.py`
: Tomo's debugger integration, loaded into `gdb` by `tomo run --debug` (see
**DEBUGGING**).

*prefix*`/man/man1/`
: Man pages, including those installed for programs built with `tomo build
--install`.