Compiler Configuration
The Runar compiler can be configured through the programmatic API, CLI flags, or a project-level configuration file. This page documents all available options and how they affect compilation.
Programmatic API: CompileOptions
When using the compiler as a library via runar-compiler, you pass a CompileOptions object to the compile() function:
import { compile } from 'runar-compiler';
const result = compile(sourceCode, {
fileName: 'P2PKH.ts',
constructorArgs: { pubKeyHash: '0x89abcdef...' },
});
Available Options
| Option | Type | Default | Description |
|---|---|---|---|
fileName | string | "contract.ts" | Source file name. Used in diagnostics and source maps. The file extension determines the parser (.ts, .go, .rs, .py). |
parseOnly | boolean | false | Stop after the parse pass. Returns only the ContractNode AST. |
validateOnly | boolean | false | Stop after the validate pass. Returns the AST and validation diagnostics. |
typecheckOnly | boolean | false | Stop after the type-check pass. Returns the AST with type annotations. |
constructorArgs | Record<string, bigint | boolean | string> | undefined | Constructor arguments to bake into the compiled script. When provided, the emitter replaces OP_0 placeholders with actual values. |
disableConstantFolding | boolean | false | When true, disables the constant folder optimization. Constant folding is enabled by default. |
Early Exit Options
The parseOnly, validateOnly, and typecheckOnly options cause the compiler to stop at progressively later stages. This is useful for tooling (IDE integrations, linters) and debugging.
// Parse only -- get the AST for syntax analysis
const parseResult = compile(source, { parseOnly: true });
console.log(parseResult.contract); // ContractNode | null
console.log(parseResult.errors); // CompilerDiagnostic[]
// Validate only -- check structural rules
const validateResult = compile(source, { validateOnly: true });
console.log(validateResult.errors); // CompilerDiagnostic[]
console.log(validateResult.warnings); // CompilerDiagnostic[]
// Typecheck only -- verify types without lowering
const typecheckResult = compile(source, { typecheckOnly: true });
console.log(typecheckResult.errors); // CompilerDiagnostic[]
When none of these flags are set, the compiler runs all six passes and produces the full output.
Constructor Arguments
Constructor arguments can be provided at compile time to produce a fully resolved script (no placeholders):
const result = compile(source, {
constructorArgs: {
pubKeyHash: '89abcdef01234567890abcdef01234567890abcd',
},
});
// result.scriptHex is the final script with pubKeyHash embedded
// No OP_0 placeholders remain
If constructorArgs is not provided, the compiled script contains OP_0 placeholders at the positions where constructor arguments should be inserted. The SDK fills these in at deployment time.
Individual Pass Functions
In addition to the unified compile() function, the compiler exports each pass as a standalone function for fine-grained control:
import { parse, validate, typecheck, lowerToANF } from 'runar-compiler';
// Step through passes manually
const parseResult = parse(source, 'Counter.ts');
const validationResult = validate(parseResult.contract);
const typecheckResult = typecheck(validationResult);
const anfProgram = lowerToANF(typecheckResult.typedContract);
Function Signatures
parse(source: string, fileName?: string): ParseResult
// ParseResult: { contract: ContractNode | null; errors: CompilerDiagnostic[] }
validate(contract: ContractNode): ValidationResult
// ValidationResult: { errors: CompilerDiagnostic[]; warnings: CompilerDiagnostic[] }
typecheck(contract: ContractNode): TypeCheckResult
// TypeCheckResult: { typedContract: ContractNode; errors: CompilerDiagnostic[] }
lowerToANF(contract: ContractNode): ANFProgram
// ANFProgram: { contractName: string; properties: ANFProperty[]; methods: ANFMethod[] }
These functions are useful when building custom tooling on top of the Runar compiler, such as IDE plugins, documentation generators, or alternative backends.
CLI Configuration
The runar compile command exposes compiler options as command-line flags.
Basic Usage
runar compile <files...> [options]
The <files...> argument accepts one or more source files or glob patterns:
# Single file
runar compile contracts/P2PKH.runar.ts
# Multiple files
runar compile contracts/P2PKH.runar.ts contracts/Counter.runar.ts
# Glob pattern
runar compile contracts/*.runar.ts
CLI Flags
| Flag | Description |
|---|---|
--output <dir> | Output directory for compiled artifacts. Defaults to ./artifacts. |
--ir | Include the ANF intermediate representation in the artifact JSON. Useful for debugging and cross-compiler verification. |
--asm | Print assembly to stdout (ASM is always included in the artifact). |
--disable-constant-folding | Disable the constant folder optimization (enabled by default). |
Examples
# Compile with full debug output
runar compile contracts/P2PKH.runar.ts --output ./artifacts --ir --asm
# Compile with constant folding disabled
runar compile contracts/Counter.runar.ts --disable-constant-folding --output ./build
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Compilation succeeded |
| 1 | Any compilation failure (parse error, validation error, type error, or internal error) |
Diagnostics are printed to stderr. The compiled artifact (if any) is written to the output directory.
Optimizer Settings
The compiler includes three optimizer passes. Here is how to control them.
Peephole Optimizer
The peephole optimizer is always enabled and cannot be disabled. It applies safe, mechanical transformations to the Stack IR that reduce script size without changing behavior. These transformations are well-tested and have no tradeoffs.
ANF EC Optimizer
The ANF EC optimizer is enabled by default for contracts that use elliptic curve operations. It applies algebraic simplification rules specific to secp256k1. If your contract does not use EC operations, this optimizer has no effect.
Constant Folder
The constant folder is enabled by default. Disable it with disableConstantFolding: true in the API or --disable-constant-folding on the CLI.
The constant folder evaluates expressions with all-literal arguments at compile time. For example:
// Before constant folding:
let hash = sha256(0x68656c6c6f);
// After constant folding:
let hash = 0x2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824;
Why might you disable it? Constant folding changes the script bytes, which changes the script hash, which changes the contract address. In audit and verification contexts, this can be confusing — the auditor expects to see the sha256 call in the script, not a precomputed constant. Disable constant folding with disableConstantFolding: true or --disable-constant-folding when you need the unfolded script for auditing.
What’s Next
- Output Artifacts — Understand the structure of compiled artifact files
- How the Compiler Works — Architecture overview and design decisions