CLI reference
The pluvial binary is both the compiler and the runtime. Running it with no arguments
starts the REPL; running it with a file compiles and runs that file.
Entry points
Section titled “Entry points”pluvial # start the REPL (no arguments)pluvial file.plu # compile and run file.plupluvial run file.plu # explicit run subcommandpluvial --version # print the version and exitpluvial -v # same as --versionpluvial --help # print usage and exitpluvial -h # same as --helppluvial file.pluis the standard way to run a program. The.pluextension is a convention, not a requirement.runandcheckare additions, not replacements —pluvial file.plustill runs the file implicitly.--helpis written tostdout(so it can be piped to a pager); a usage error is written tostderrand exits with code 64.
Subcommands
Section titled “Subcommands”pluvial run file.plu [args...]Compiles and runs the file. Trailing arguments are available to the program through
std/os’s args().
pluvial check file.pluCompiles the source and reports type errors without executing the program — a dry run for editor integration, pre-commit hooks, and CI.
- On success: exit 0, no output (“no news is good news”), so
pluvial check $f && next-stepcomposes naturally. - On failure: exit 65, printing the full error block (colored if
stderris a TTY).
format
Section titled “format”pluvial format [--check] <file>...pluvial format - # read stdin, write stdoutFormats source files. The style is: 4-space indentation, { kept on the keyword line
(def f() int {, } else {), spaces around binary operators and after commas, no trailing
whitespace, and a single trailing newline. Parentheses are placed precedence-aware (the
minimum needed to reproduce the same AST).
- Formatting is idempotent —
format(format(x)) == format(x). - Comments are not preserved (the scanner removes them before the AST).
--checkprints a diff and exits 1 when there is a formatting difference (exit 0 when there is none) — useful as a CI gate.
pluvial test [file|dir] # no argument → current directoryRuns tests. A directory is searched recursively for *_test.plu files. Tests are written
with std/test. Output looks like:
===== pluvial test =====
math_test.plu ✓ add works ✗ multiply fails expected: 0 got: 1
===== 3 passed, 1 failed =====When everything passes, the summary is ===== N passed =====.
pluvial doc file.plu # generate Markdown to stdoutpluvial doc -o dir/ # write Markdown files to a directoryGenerates documentation from ## doc comments, which attach to the declaration that
follows them (def, struct, enum, or a top-level variable).
pluvial lspStarts a Language Server Protocol server over stdin/stdout (JSON-RPC 2.0 with
Content-Length framing). It provides diagnostics (publishDiagnostics), hover
(textDocument/hover), and go-to-definition (textDocument/definition). A VS Code
extension (vscode-pluvial) is provided; other editors can point their LSP client at
pluvial lsp directly.
pluvial build file.plu [-o name]Ahead-of-time compilation. Pluvial lowers the program through its SSA IR to LLVM IR and
produces a stand-alone native executable. It resolves the dependency closure, caches
per-module objects under ~/.pluvial/cache/, and links everything into one binary. This
requires LLVM (llc) and clang. (pluvial run and the REPL always use the bytecode VM
and are unaffected.)
The REPL
Section titled “The REPL”Running pluvial with no arguments starts an interactive Read-Eval-Print Loop:
$ pluvialPluvial REPL — type 'exit' to quit> 1 + 23> "hello".to_upper()HELLO> int x = 5> x + 16> def double(int n) int { return n * 2 }> double(7)14> exit$- Typing an expression prints its value. Declarations, assignments, and control-flow statements do not print.
- Declarations persist across lines — globals, functions, and structs stay defined for the whole session.
- Errors do not end the session. A compile error (65) or runtime error (70) prints its block and re-prompts; the session state is untouched.
- Re-declaring a global is allowed in the REPL (the slot and type can be replaced), because the previous line has already run. Re-declaring a function or struct is still an error, as in file mode.
- The session ends on EOF (Ctrl-D) or by typing
exit/quiton a line.
Exit codes
Section titled “Exit codes”Pluvial follows the sysexits convention:
| Code | Meaning |
|---|---|
| 0 | Success |
| 64 | Misuse of the CLI (wrong number of arguments) |
| 65 | Compile error (type error, syntax error, static error) |
| 66 | Could not open or read the input file |
| 70 | Runtime error (division by zero, stack overflow) |
Colored error output
Section titled “Colored error output”Error blocks use ANSI color when stderr is a TTY:
error:/runtime error:— bold red--> file:line:col— bold- caret span
^^^— bold red = help:— bold blue- gutter
|and the source line — unstyled
When stderr is not a TTY (pipes, CI, test harnesses), color is suppressed entirely and
the output is byte-identical to the uncolored form.