
The Vary compiler takes `.vary` source files and produces JVM bytecode. It is an ahead-of-time compiler: there is no interpreter.

The compiler is written in Kotlin. It shares the JVM runtime with the code it produces. The bytecode generator uses the ASM library directly, and runtime support functions are `@JvmStatic` methods that compiled Vary code calls without a foreign function boundary. Kotlin's sealed classes model the AST, coroutines drive the language server, and the Java ecosystem provides classloader isolation for the mutation engine.

## How it works

The compiler is a pipeline. Each stage takes the output of the previous stage and produces a new representation:

```text
Source text
  → Lexer (tokens)
  → Parser (AST)
  → Constant folder (optimized AST)
  → Dead code eliminator (trimmed AST)
  → Type checker (typed AST + symbol table)
  → Bytecode generator (JVM .class bytes)
```

There is no intermediate representation between the AST and JVM bytecode. The codegen phase walks the typed AST and emits bytecode instructions directly. This keeps the compiler simple, auditable, and deterministic.

## Compilation model

Modules are compiled recursively. When the type checker encounters an `import`, it compiles the imported module first, extracts its public type signatures, and continues checking the importing module. The full module graph is then traversed to determine load order.

Compilation is deterministic given the same source, compiler version, and flags. Compiled bytecode is cached using a content-addressed scheme keyed on the SHA-256 hash of those inputs. Multiple variants of the same file (normal, debug, coverage, mutation) coexist in the cache without conflict. When the source has not changed, recompilation is skipped entirely.

## What ships in the compiler

The compiler is a single fat JAR that includes:

| Capability | Command |
|------------|---------|
| Run programs | `vary run` |
| Type checking | `vary check` |
| Test runner | `vary test` |
| Mutation testing | `vary mutate` |
| Code formatter | `vary fmt` |
| Language server | `vary lsp` |
| Project scaffolding | `vary new` |
| Artifact caching | `vary cache` |
| Build and package | `vary build` |

See the [CLI reference](/docs/cli/) for the full list.

## Type system

Vary's type system maps directly to the JVM:

| Vary type | JVM type |
|-----------|----------|
| `Int` | `long` (64-bit) |
| `Float` | `double` (64-bit) |
| `Bool` | `boolean` |
| `Str` | `String` |
| `List[T]` | `ArrayList` |
| `Dict[K, V]` | `HashMap` |
| `Set[T]` | `HashSet` |

One integer type and one float type. No width selection, no signed/unsigned distinction. This is a deliberate simplification.

Null safety is enforced at compile time. `T?` marks a value that may be `None`. Flow narrowing inside `if x is not None { }` blocks promotes `T?` to `T` without wrapper types or monadic syntax.

## Contracts

Functions can declare `in {}` preconditions, `out(r) {}` return-value postconditions, and `old()` entry-state captures. Classes and data types can declare `invariant {}` blocks. These all compile to runtime checks that throw `ContractViolation` on failure. The mutation engine treats contract violations as kills, so contracts double as test oracles without additional test code. See [Contracts](/docs/contracts/) for the full reference.

## Mutation

Mutation testing operates at both AST and JVM bytecode levels. Bytecode mutation patches individual instructions and runs each variant in an isolated classloader, reusing the artifact cache. AST mutation rewrites the syntax tree before compilation. Both levels are built into the compiler, not bolted on as external tools. See [Mutation testing](/docs/mutation/testing/) for details.

## What the compiler does not do

| Omission | Detail |
|----------|--------|
| No IR | There is no intermediate representation between the AST and JVM bytecode. |
| No interpreter | Vary is always compiled ahead of time. |
| No incremental compilation | The artifact cache provides fast rebuilds, but within a single file, compilation is all-or-nothing. |
