* Documentation

Tooling

The turf CLI: flags, --explain, --smart, building from source, and the test suite.

Turf’s tooling today is centered on a single CLI compiler binary, turf, which also runs a fixed set of compile-time static analyses and prints human-friendly, color-coded diagnostics on every build.

Basic invocation

turf <input.tr> -o <output_name>
./<output_name>

The input file’s name must end in .tr — anything else is a hard error. If -o is omitted, the output name defaults to the input filename’s basename with .tr stripped.

Flags

FlagImpliesWhat it does
--emit-llvm—Writes human-readable LLVM IR to <output>.ll instead of compiling and linking a native binary.
--smart—Enables the SLM (AI-assisted) fix-suggestion pipeline. See SLM Integration.
--dump-ast—Prints the parsed AST (functions/structs, then top-level statements). Runs before the Resolver, so nodes show no resolution annotations.
--resolve—Prints a [Resolver] banner confirming the Resolver pass succeeded, plus the final scope depth.
--dump-resolver-symbols--resolveSame banner, plus a full dump of the symbol table.
--dump-resolved--resolveSame banner, plus an AST dump annotated with a resolved/not-resolved badge per node.
--typecheck--resolvePrints a [TypeChecker] banner confirming pass/fail status.
--dump-typechecked--resolve + --typecheckSame banner, plus an AST dump annotated with each node’s inferred type and module qualifiers. Only printed if type-checking succeeded.
--dump-modules--resolveDumps module-system introspection: imports, type ownership, flat function tables.
-o <name>—Sets the output binary/IR base name.
--link <lib>—Adds -l<lib> to the final linker invocation, on top of any libraries a program’s own extern from "libname" fn declarations already pull in. Repeatable.

These flags don’t turn the passes on. The Resolver and TypeChecker run unconditionally on every compile, regardless of any flag. --resolve, --typecheck, and the --dump-* family only control whether extra banners or AST dumps are printed. If either pass fails, compilation aborts before code generation ever sees the AST — flags or no flags.

--explain E0NN

turf --explain E001

A separate mode that takes no .tr input at all. Prints a header (E0NN ClassName (CATEGORY)) followed by the explanation text, then exits.

$ turf --explain E001
E001  ArrayBoundsError (ARRAY_ERROR)

You tried to reach past the end of an array
...

As of v1.0.0 there are 68 registered error codes, E001–E068, each assigned once and never reassigned (assignment order is alphabetical by source file and class name at the time each was added — it’s an opaque identifier, not a severity ranking).

A small curated subset is flagged Important — non-obvious concepts where the one-line message alone isn’t enough, and worth reading the full --explain entry before patching: E010 (RecursionWithoutBaseError), E017 (DoubleFreeError), E018 (UseAfterFreeError), E035 (InvalidTransitionError), E036 (InvalidTransitionTargetError).

Reading a diagnostic

── error at line 4, col 12 [E001], in file geometry.tr

You tried to reach past the end of an array

Note: declared here (line 2, col 5)
Hint: array size is fixed at declaration — did you mean a smaller index?
   4 │ mut last: int = primes[3];
     │                        ^ Here!

Run `turf --explain E001` for more details.

Top to bottom: a header (bright red for errors, bright yellow for warnings), the message body, zero or more blue Note: lines for related source locations (e.g. a variable’s declaration site), an optional green Hint: line, a source snippet with the offending token underlined, and — for diagnostics with a resolved code — a footer pointing at --explain.

If a diagnostic has already fired on a given source line, every subsequent diagnostic on that same line is silently dropped, so one root-cause typo doesn’t produce a wall of downstream noise. Output is always sorted by (line, column), reflecting the source file rather than the order compiler passes happened to run in.

”Did you mean?”

Unknown variables, types, keywords, struct fields, struct methods, module symbols, and enum variants get typo-correction suggestions via restricted Damerau-Levenshtein distance (adjacent-character transpositions count as one edit, not two):

$ turf typo.tr
── error [E0NN]
Undeclared variable 'contuner'.
Hint: did you mean 'container'?

Compile-time static analysis

Turf builds a control-flow graph for every function body and runs a fixed sequence of analyses over it, unconditionally, on every compile — separate from ordinary type checking:

Building from source

Requirements

Build

git clone --recursive <this-repo>
cd turf
chmod +x scripts/cmake_build.sh
./scripts/cmake_build.sh --release

cmake_build.sh detects available CPU cores and builds in parallel; the resulting binary is placed at build/turf. On first run, if llama.cpp’s static libraries aren’t already built, CMake builds them automatically before building Turf itself — this can take a while the first time.

Compile and run a file directly

./scripts/compile_and_run.sh path/to/file.tr

Compiles, runs, and cleans up the produced binary.

Test suite

From the repo root, after building the turf binary:

./scripts/test_runner.sh

What’s not here yet

There is no LSP server, no turf fmt, no turf test, and no package manager as of v1.0.0 — see Roadmap for what’s planned.