Diagnostics & Warnings
Achronyme reports errors and warnings with source snippets, underline carets, and actionable suggestions — similar to rustc. The diagnostic system works across all commands (run, compile, circuit, disassemble).
Error Output
Section titled “Error Output”By default, errors render with source context:
error: undefined variable: `conuter` --> 3:9 |3 | let y = conuter + 1 | ^^^^^^^ | = help: did you mean `counter`?The output includes:
- Severity —
errororwarning, with an optional code like[W001] - Location —
file:line:col(orline:colfor stdin) - Source snippet — the offending line with underline carets (
^^^) - Labels — secondary spans pointing to related locations
- Notes — additional context (
= note: ...) - Suggestions — actionable fixes (
= help: ...)
Compiler Warnings
Section titled “Compiler Warnings”The compiler emits warnings for code that is valid but likely incorrect. Warnings never prevent compilation.
W001: Unused Variable
Section titled “W001: Unused Variable”Triggers when a local variable or function parameter is never read:
let count = 42// warning[W001]: unused variable: `count`Prefix with _ to silence the warning:
let _count = 42 // no warningW002: Unused Mutable
Section titled “W002: Unused Mutable”Triggers when a variable is declared with mut but never reassigned:
let mut total = 0print(total)// warning[W002]: variable `total` declared as mutable but never mutatedRemove the mut keyword if the variable doesn’t need to change.
W003: Unreachable Code
Section titled “W003: Unreachable Code”Triggers when statements follow a return in the same block:
fn foo() { return 1 let x = 2 // warning[W003]: unreachable code}W004: Variable Shadowing
Section titled “W004: Variable Shadowing”Triggers when a new binding shadows an existing variable in the same scope:
let x = 1let x = 2 // warning[W004]: variable `x` shadows a previous binding in the same scopeW005: Unused Selective Import
Section titled “W005: Unused Selective Import”Triggers when a name brought in by a selective import is never used:
import { add, PI } from "./math.ach"print(add(1, 2))// warning[W005]: imported name `PI` is never usedPrefix with _ to silence the warning:
import { add, _PI } from "./math.ach"print(add(1, 2)) // no warning for _PIThis warning only applies to selective imports (import { ... } from). Namespace imports (import "..." as alias) are not checked because the alias is a single binding.
”Did You Mean?” Suggestions
Section titled “”Did You Mean?” Suggestions”When the compiler encounters an undefined variable, it searches all in-scope names (locals, globals, upvalues) for similar identifiers using Levenshtein distance. If a close match is found, it suggests the correction:
error: undefined variable: `prnt` --> 2:1 |2 | prnt("hello") | ^^^^ | = help: did you mean `print`?The suggestion threshold scales with name length — short names (3 characters or fewer) require a closer match to avoid false suggestions.
Output Formats
Section titled “Output Formats”The --error-format flag controls how diagnostics are rendered. It applies globally to all subcommands.
human (default)
Section titled “human (default)”Rich output with source snippets, underline carets, and ANSI colors (when stderr is a terminal):
ach run program.ach --error-format humanOne JSON object per diagnostic (JSON Lines format), suitable for editor integrations and CI pipelines:
ach run program.ach --error-format json{"code":"W001","level":"warning","message":"unused variable: `x`","notes":["if this is intentional, prefix with underscore: `_x`"],"spans":[{"byte_end":5,"byte_start":4,"column_end":6,"column_start":5,"file_name":null,"label":"primary","line_end":1,"line_start":1}],"suggestions":[]}Each JSON object contains:
| Field | Type | Description |
|---|---|---|
message | string | The diagnostic message |
code | string|null | Warning/error code (e.g., "W001") |
level | string | "error", "warning", "note", or "help" |
spans | array | Source locations with byte offsets, line/col, and labels |
notes | array | Additional context strings |
suggestions | array | Suggested code replacements with spans |
Compact one-line format, grep-friendly:
ach run program.ach --error-format short<stdin>:3:9: error: undefined variable: `x`Format: file:line:col: severity: message
Error Recovery
Section titled “Error Recovery”The parser collects multiple errors per compilation instead of stopping at the first one. Failed regions appear as Error nodes in the AST, allowing the parser to continue and report additional issues:
$ ach compile broken.acherror: expected expression --> 1:9 |1 | let x = | ^ |error: unexpected token `}` --> 3:1 |3 | } | ^ |This means a single compilation run can surface multiple problems at once, reducing the edit-compile-fix cycle.