Skip to content

Tooling

Terminal window
fern [-target arm64|arm64-darwin|x86-64|wasm] [-o OUTPUT] [--run] FILE.fern
fern -fmt [-w | -d] FILE.fern
fern -interp FILE.fern
fern -repl
FlagDefaultMeaning
-targetarm64Backend: arm64, arm64-darwin, x86-64, wasm.
-ostdoutOutput binary path. Without it, assembly prints to stdout.
--runoffCompile + execute the produced binary. Returns its exit code.
-ccccLinker for native targets (gcc, clang, …).
-qemunonePath to a qemu-* binary for cross-arch execution under --run.
-fmtoffFormat the source. -w writes back; -d prints a diff.
-interpoffRun the AST interpreter (skips codegen entirely).

fern -fmt rewrites a file to the canonical style: two-space indent, one statement per line, trailing newline at EOF. Comments survive the round trip in their original position.

Terminal window
fern -fmt -w foo.fern # rewrite in place
fern -fmt -d foo.fern # show the diff instead

The formatter is idempotent: fern -fmt | fern -fmt produces identical output.

Speaks LSP over stdin/stdout. Spawn it from any editor with a generic LSP client. Features:

  • Diagnostics — parser + type-check errors, routed per-file in multi-module programs.
  • Hover — types for variables, parameters, fields, methods, cross-module references.
  • Goto-definition — across files in workspace mode.
  • Completion — locals, params, top-level decls, variants, keywords. Triggered on . and Ctrl/Cmd-Space.
  • Signature help — function signatures with active-parameter highlighting.
  • Inlay hints — inferred types for var x = ….
  • Document symbols — outline view (Cmd-Shift-O in VS Code).
  • Semantic tokens — type-aware syntax highlighting.
  • Find references + rename — workspace-wide, including method calls / struct fields / enum variants.
  • Format on save — runs the formatter via textDocument/formatting.

Lives at editors/vscode/. Install with:

Terminal window
cd editors/vscode
npm install
npm run compile
npx @vscode/vsce package
code --install-extension fern-vscode-0.1.0.vsix

Set fern.serverPath if fern-lsp isn’t on your $PATH.

Terminal window
fern -repl
> var x = 7;
> x * 2
14

State persists across lines. Multi-line forms (an if block, function decl, etc.) are one logical input — the REPL reads until braces balance.

Fern’s pure-Fern test runner lives in std/test. Tests are ordinary .fern files — run them with -interp (or compile + execute the produced binary):

Terminal window
fern -interp my_test.fern # AST interpreter
fern my_test.fern -o my_test --run # compile + run

Output is TAP-13. Exit code is 0 when every case passes and 1 on any failure, so any TAP-aware CI runner (prove, tape, tap-junit) works without further config.

See the Testing tutorial for the authoring shape and assertion catalogue.