Ashes Compiler CLI Specification
This document is the authoritative reference for every command, flag, and argument supported by the Ashes compiler CLI (ashes).
Source of truth: The CLI entry point and all argument-parsing logic live in
src/Ashes.Cli/Program.cs. Update that file—and this document—together whenever CLI behaviour changes.
Overview
The Ashes CLI is invoked as:
ashes <command> [options] [arguments]Running ashes with no arguments (or an unrecognised command) prints the help text and exits with code 2.
Running ashes --help (or ashes -h) prints the same help text and exits with code 0. Running ashes <command> --help (or ashes <command> -h) also prints the CLI help text and exits with code 0.
Command List
| Command | Short description |
|---|---|
ashes compile | Compile an Ashes source file/expression to a native executable |
ashes run | Compile and immediately execute an Ashes program |
ashes repl | Start an interactive read-eval-print loop |
ashes test | Run .ash test files and compare against // expect: comments |
ashes fmt | Format .ash source files |
ashes init | Create a new Ashes project in the current directory |
ashes add | Add a dependency to the project manifest (--path, --dev) |
ashes remove | Remove a dependency from the project manifest |
ashes restore | Resolve dependencies (path + registry); --frozen, --offline |
ashes tree | Render the resolved dependency tree |
ashes why | Show why a package is in the dependency graph |
ashes login | Store an API token for a registry |
ashes publish | Package the current project and publish it to a registry |
ashes yank | Yank (or --undo) a published version |
ashes search | Search a registry for packages |
ashes info | Show a package's versions, owners, and capabilities |
Registry commands
These talk to an Ashes package registry (see the registry API reference). Each accepts --registry <name-or-url>, resolving a name from ~/.ashes/config.json (the default entry falls back to the canonical public instance) or using a literal http(s):// URL as-is. Credentials are stored per registry base URL in ~/.ashes/credentials.json.
| Command | Synopsis | Notes |
|---|---|---|
ashes login | ashes login [--registry <r>] (--as <account> | --token <t>) | --as mints a token via the registry; --token stores a provided one. |
ashes publish | ashes publish [--registry <r>] [--project <ashes.json>] [--version <v>] | Packages the project's .ash sources (plus ashes.json/README/LICENSE), computes the ash1: content hash, and uploads. Namespace derives from namespace or the PascalCase package name; version from --version or the manifest. Requires a prior login. |
ashes yank | ashes yank <namespace> <version> [--undo] [--registry <r>] | Marks a version un-resolvable for new builds (existing locks still resolve); --undo reverses it. Owner-only. |
ashes search | ashes search <query> [--registry <r>] | Prints a ranked list (namespace, latest, description). |
ashes info | ashes info <namespace>[@<version>] [--registry <r>] | Shows owners and, for the selected (or latest) version, its capability row and dependencies. |
The capability row shown by ashes info is the registry's server-computed audit — the capabilities the package's public API needs, inferred by the compiler at publish time, not a heuristic scan.
Common Options
The following help flags are accepted at the top level and for each command:
| Option | Value type | Default | Repeatable | Description |
|---|---|---|---|---|
--help / -h | — | — | No | Print CLI help text and exit successfully. |
The following options are accepted by compile, run, repl, and test:
| Option | Value type | Default | Repeatable | Description |
|---|---|---|---|---|
--target <id> | enum | OS-dependent (see below) | No | Select the code-generation back end. |
--target-cpu <cpu> | string | generic / x86-64 | No | Target a specific CPU microarchitecture (e.g. skylake, znver3, apple-m1). Use native to auto-detect the host CPU. Default is safe generic codegen for the target arch. |
--parallel-stack-size <size> | size | 1M | No | Per-worker stack size for structured parallelism (Ashes.Task.Parallel). Accepts a byte count or a K/M/G suffix (e.g. 2M, 1048576); must be positive. On linux this sets the mmap'd worker-stack length; on win-x64 it is passed to CreateThread (unset leaves the OS default). |
--parallel-workers <n> | int | core count | No | The executable's compiled maximum / hard ceiling for concurrent structured-parallelism workers. Must be positive. When unset, the compiled program detects the machine's core count once at first fork (linux: sched_getaffinity popcount, so taskset/cgroup masks are respected; win-x64: GetSystemInfo), falling back to 8 if detection fails. A program can request fewer workers for a scoped computation with Ashes.Task.Parallel.withWorkers (effective count is min(override, this maximum)); it can never exceed this ceiling. |
-O0|-O1|-O2|-O3 | enum | -O2 | No | Select LLVM optimization level. |
The following option is accepted by compile and run only:
| Option | Value type | Default | Repeatable | Description |
|---|---|---|---|---|
--debug / -g | bool (flag) | false | No | Emit DWARF debug info into the output binary. See Debug Mode below. |
Optimization level values:
| Flag | Meaning |
|---|---|
-O0 | No optimization |
-O1 | Basic optimizations |
-O2 | Standard optimizations (default) |
-O3 | Aggressive optimizations |
--project is accepted by compile, run, and test only (not by ashes repl):
| Option | Value type | Default | Repeatable | Description |
|---|---|---|---|---|
--project <path> | file path | — | No | Load a project manifest (ashes.json). Mutually exclusive with an inline file argument and --expr. |
--target values:
| Value | Platform |
|---|---|
linux-x64 | Linux x86-64 — emits a native ELF64 binary |
linux-arm64 | Linux AArch64 — emits a native ELF64 binary |
win-x64 | Windows x86-64 — emits a native PE32+ binary |
win-arm64 | Windows on ARM64 — emits a native PE32+ (AArch64) binary, and is also a host RID (a released compiler runs on Windows-on-ARM). Neither the emitted image nor the WoA compiler executes on an x64 host — both run only on native ARM64 Windows |
Any other value is rejected with an error message and exit code 1.
Command Reference
ashes compile
Compile an Ashes program to a native executable on disk.
Synopsis
ashes compile [--target <id>] [--target-cpu <cpu>] [--parallel-stack-size <size>] [--parallel-workers <n>] [-O0|-O1|-O2|-O3] [--debug|-g] [-o <output>] <input.ash>
ashes compile [--target <id>] [--target-cpu <cpu>] [--parallel-stack-size <size>] [--parallel-workers <n>] [-O0|-O1|-O2|-O3] [--debug|-g] [-o <output>] --expr "<source>"
ashes compile [--target <id>] [--target-cpu <cpu>] [--parallel-stack-size <size>] [--parallel-workers <n>] [-O0|-O1|-O2|-O3] [--debug|-g] [-o <output>] --project <ashes.json>
ashes compile [--target <id>] [--target-cpu <cpu>] [--parallel-stack-size <size>] [--parallel-workers <n>] [-O0|-O1|-O2|-O3] [--debug|-g] [-o <output>] # discovers ashes.json upwardArguments
| Name | Type | Required | Description |
|---|---|---|---|
<input.ash> | file path | No† | Path to the .ash source file to compile. |
† Exactly one input source must be provided: a positional file, --expr, or a project (explicit or auto-discovered).
Options
| Option | Long form | Value type | Default | Repeatable | Description |
|---|---|---|---|---|---|
-o | --out | file path | Derived from input name (see below) | No | Path for the compiled output binary. |
--expr | string | — | No | Inline Ashes source to compile instead of reading a file. | |
--target | enum | OS default | No | Target back end (linux-x64, linux-arm64, win-x64, or win-arm64). | |
--target-cpu | string | generic / x86-64 | No | Target CPU microarchitecture (e.g. skylake, native). | |
--parallel-stack-size | size | 1M | No | Per-worker stack size for Ashes.Task.Parallel (byte count or K/M/G suffix). | |
--project | file path | — | No | Path to an ashes.json project file. | |
-O0|-O1|-O2|-O3 | enum | -O2 | No | Select LLVM optimization level. | |
--debug | -g | bool (flag) | false | No | Emit DWARF debug info (see Debug Mode). |
Default output path rules (when -o is not given):
- Single file
examples/hello.ash→examples/hello(Linux) orexamples/hello.exe(Windows). --exprwithout a project →out(Linux) orout.exe(Windows).- Project compile →
<outDir>/<name>(fromashes.json), appending.exeon Windows.
Defaults
| Property | Default value |
|---|---|
--target | linux-x64 on Linux x86-64, linux-arm64 on Linux ARM64, win-x64 on Windows |
--target-cpu | x86-64 for x86-64 targets, generic for ARM64 |
-o / --out | Derived from input (see above) |
-O0..-O3 | -O2 (standard optimizations) |
Exit Codes
| Code | Meaning |
|---|---|
0 | Compilation succeeded; binary written to disk. |
1 | Compilation error (parse, type, or code-generation failure), or user/input error such as missing input, file not found, wrong extension, or I/O failure. |
2 | Usage error (bad flag or conflicting options). |
Output (stdout / stderr)
Successful status messages are written to stdout via Spectre.Console. On success, a confirmation line is printed:
OK Wrote <size> to <output>
Target: <target>
Debug: yes (only when --debug / -g is set)
Time: <elapsed><size> is human-readable (e.g. 8.1 KB). <elapsed> is the compilation wall-clock time (e.g. 159ms or 1.23s).
Compiler diagnostics and command errors are written to stderr. No machine-readable output format is currently supported.
Examples
# Compile a file (output: examples/hello on Linux)
ashes compile examples/hello.ash
# Compile to an explicit path
ashes compile examples/hello.ash -o build/hello
# Compile an inline expression
ashes compile --expr 'Ashes.IO.print(40 + 2)' -o out
# Cross-compile to Windows PE
ashes compile examples/hello.ash --target win-x64 -o hello.exe
# Compile the project rooted at ashes.json
ashes compile --project path/to/ashes.json
# Auto-discover ashes.json (searches upward from cwd)
ashes compileashes run
Compile and immediately execute an Ashes program. The compiled binary is written to a uniquely named executable under the system temporary directory (for example, <temp>/ashes/) and is not automatically deleted by the CLI.
Synopsis
ashes run [--target <id>] [--target-cpu <cpu>] [--parallel-stack-size <size>] [--parallel-workers <n>] [-O0|-O1|-O2|-O3] [--debug|-g] <input.ash> [-- <args...>]
ashes run [--target <id>] [--target-cpu <cpu>] [--parallel-stack-size <size>] [--parallel-workers <n>] [-O0|-O1|-O2|-O3] [--debug|-g] --expr "<source>" [-- <args...>]
ashes run [--target <id>] [--target-cpu <cpu>] [--parallel-stack-size <size>] [--parallel-workers <n>] [-O0|-O1|-O2|-O3] [--debug|-g] --project <ashes.json> [-- <args...>]
ashes run [--target <id>] [--target-cpu <cpu>] [--parallel-stack-size <size>] [--parallel-workers <n>] [-O0|-O1|-O2|-O3] [--debug|-g] [-- <args...>] # auto-discovers ashes.jsonArguments
| Name | Type | Required | Description |
|---|---|---|---|
<input.ash> | file path | No† | Path to the .ash source file to run. |
-- <args...> | string list | No | Arguments forwarded to the compiled program (args in Ashes source). The -- separator is required. |
† Same rule as compile: one of file, --expr, or project.
Options
| Option | Value type | Default | Repeatable | Description |
|---|---|---|---|---|
--expr | string | — | No | Inline Ashes source to compile and run. |
--target | enum | OS default | No | Target back end. |
--target-cpu | string | generic / x86-64 | No | Target CPU microarchitecture (e.g. skylake, native). |
--parallel-stack-size | size | 1M | No | Per-worker stack size for Ashes.Task.Parallel (byte count or K/M/G suffix). |
--project | file path | — | No | Path to an ashes.json project file. |
-O0|-O1|-O2|-O3 | enum | -O2 | No | Select LLVM optimization level. |
--debug / -g | bool (flag) | false | No | Emit DWARF debug info (see Debug Mode). |
Exit Codes
| Code | Meaning |
|---|---|
0 | Program compiled and exited with code 0. |
| Non-zero (from program) | The compiled program's own exit code is propagated as-is. |
1 | Compilation error or user/input failure (before the program starts). |
2 | Usage error. |
Output (stdout / stderr)
The compiled program's stdout and stderr flow directly to the terminal without interception. No extra diagnostic lines (timing, size, etc.) are printed, so ashes run output is safe to pipe. Compiler diagnostics are printed to the CLI's stderr before the program runs.
Examples
# Run a file
ashes run examples/hello.ash
# Run with arguments passed to the program
ashes run examples/hello.ash -- hello world
# Run an inline expression
ashes run --expr 'Ashes.IO.print(40 + 2)'
# Run the auto-discovered project
ashes run
# Run a named project
ashes run --project examples/project/ashes.jsonashes repl
Start an interactive read-eval-print loop. Each expression is compiled to a temporary binary, executed, and its stdout is displayed.
Synopsis
ashes repl [--target <id>] [--target-cpu <cpu>] [-O0|-O1|-O2|-O3]Options
| Option | Value type | Default | Repeatable | Description |
|---|---|---|---|---|
--target | enum | OS default | No | Target back end used for all REPL evaluations. |
--target-cpu | string | generic / x86-64 | No | Target CPU microarchitecture used for all REPL evaluations. |
-O0|-O1|-O2|-O3 | enum | -O2 | No | Select LLVM optimization level used for all REPL evaluations. |
REPL Commands (typed at the prompt)
| Command | Aliases | Description |
|---|---|---|
:help | :h | Show REPL help. |
:quit | :q, :exit | Exit the REPL (exit code 0). |
:target | Show the current target. | |
:target linux-x64|linux-arm64|win-x64|win-arm64 | Change the active target for subsequent expressions. |
Multi-line input is supported: if the parser detects an incomplete expression (unbalanced parentheses or an expected-token error), the REPL shows a ...> continuation prompt.
Exit Codes
| Code | Meaning |
|---|---|
0 | User exited cleanly (:quit / :exit / :q). |
2 | Usage error (unknown flag). |
Output (stdout / stderr)
All REPL output (prompts, results, errors) is written to stdout. Compiled-program stderr is relayed and highlighted in red.
Examples
ashes repl
# ashes> Ashes.IO.print(40 + 2)
# 42
# ashes> :target linux-x64
# Target set to linux-x64
# ashes> :quitashes test
Discover and execute .ash test files. A test file must contain a leading // expect: comment; the runner compiles the file, executes it, and compares stdout against the expected value.
Synopsis
ashes test [--target <id>] [--target-cpu <cpu>] [-O0|-O1|-O2|-O3] [--project <ashes.json>] [paths...]Arguments
| Name | Type | Required | Description |
|---|---|---|---|
[paths...] | file/directory path list | No | One or more .ash files or directories to search for tests. Repeatable. When --project is supplied and no paths are given, the default search root is <projectDir>/tests if that directory exists, otherwise it is the project directory itself. |
Options
| Option | Value type | Default | Repeatable | Description |
|---|---|---|---|---|
--target | enum | OS default | No | Target back end for test compilation. |
--target-cpu | string | generic / x86-64 | No | Target CPU microarchitecture for test compilation. |
--project | file path | — | No | Load a project manifest. When no explicit [paths...] are given, test discovery uses <projectDir>/tests if that directory exists; otherwise it falls back to the project directory itself. |
-O0|-O1|-O2|-O3 | enum | -O2 | No | Select LLVM optimization level for test compilation. |
Test File Conventions
A test file is a regular .ash source file with one or more leading comment directives:
// expect: <expected stdout>
// exit: <expected exit code> (optional; defaults to 0)- Only the first
// expect:line is used. // exit:must appear before// expect:.- Files without
// expect:are reported as SKIP (treated as pass).
Special expected value:
| Value | Meaning |
|---|---|
empty | Expect empty stdout. |
Example:
// exit: 1
// expect: empty
panic("empty")Exit Codes
| Code | Meaning |
|---|---|
0 | All tests with // expect: passed (or none found). |
1 | One or more tests failed. |
2 | Usage error. |
Output (stdout / stderr)
Results are printed as a table to stdout:
Test Result Time
──────────────────────────────
hello.ash PASS 5ms
failing.ash FAIL 12msA summary line follows: N passed, N failed, N skipped in <elapsed>. Failure details (expected vs. actual stdout) are printed after the table.
Examples
# Run all tests in the default location
ashes test
# Run tests in a specific directory
ashes test tests/
# Run a single test file
ashes test tests/hello.ash
# Run tests for a named project
ashes test --project path/to/ashes.jsonashes fmt
Format .ash source files. ashes fmt resolves formatting from the nearest .editorconfig (walking upward from each file), supporting:
indent_style = space|tabindent_size = <int>|tabtab_width = <int>end_of_line = lf|crlf
Defaults when not provided are 4 spaces and platform newline. Without -w, formatted output is printed to stdout. With -w, files are updated in place.
Synopsis
ashes fmt <file|dir> [-w]Arguments
| Name | Type | Required | Description |
|---|---|---|---|
<file|dir> | file/directory path | Yes | A single .ash file or a directory. When a directory is given, all .ash files are found recursively. |
Options
| Option | Long form | Value type | Default | Repeatable | Description |
|---|---|---|---|---|---|
-w | --write | bool (flag) | false | No | Write formatted output back to the source file(s) instead of printing to stdout. |
Exit Codes
| Code | Meaning |
|---|---|
0 | Formatting succeeded (or no .ash files found). |
1 | Parse error in one of the source files, or user/input error such as missing path, wrong extension, or path not found. |
2 | Usage error (bad flag or ambiguous arguments). |
Output (stdout / stderr)
- Without
-w: formatted source is written to stdout. When multiple files are formatted, a separator rule is printed before each file. - With
-w: a summary line (OK Formatted N file(s) in <elapsed>.) is written to stdout. Files that are already correctly formatted are not rewritten.
Examples
# Preview formatting of a single file
ashes fmt examples/hello.ash
# Format all .ash files in a directory, writing in place
ashes fmt examples -w
# Preview formatting for all .ash files in a directory
ashes fmt examplesashes init
Create a new Ashes project in the current directory by scaffolding an ashes.json manifest and a starter src/Main.ash entry file.
Synopsis
ashes initArguments
None.
Options
None.
Behaviour
- If
ashes.jsonalready exists in the current directory, the command fails with exit code 1. - Creates
ashes.jsonwithname(derived from the directory name),entryset to"src/Main.ash", andsourceRootsset to["src"]. - Creates the
src/directory if it does not exist. - Creates
src/Main.ashwith a hello-world program. If the file already exists it is not overwritten.
Exit Codes
| Code | Meaning |
|---|---|
0 | Project created successfully. |
1 | ashes.json already exists or an I/O error occurred. |
Examples
mkdir myapp && cd myapp
ashes init
# Created ashes.json
# Created src/Main.ashashes add
Add a dependency to the nearest ashes.json project manifest.
Synopsis
ashes add <package> [--path <dir>] [--dev]Arguments
| Name | Type | Required | Description |
|---|---|---|---|
<package> | string | Yes | The dependency name to add. |
Options
| Name | Description |
|---|---|
--path <dir> | Record a path dependency { "path": "<dir>" } instead of a registry version. |
--dev | Write to devDependencies instead of dependencies. |
Behaviour
- Discovers
ashes.jsonby walking upward from the current directory (same discovery as other commands). - If no
ashes.jsonis found, the command fails with exit code 1. - Adds the dependency to
dependencies(ordevDependencieswith--dev):{ "path": "<dir>" }when--pathis given, otherwise the SemVer string"*". Existing entries are overwritten; other dependencies are preserved.
Exit Codes
| Code | Meaning |
|---|---|
0 | Dependency added successfully. |
1 | No ashes.json found, missing package argument, or I/O error. |
Examples
ashes add json-parser
# Added json-parser to dependencies.ashes remove
Remove a dependency from the nearest ashes.json project manifest.
Synopsis
ashes remove <package>Arguments
| Name | Type | Required | Description |
|---|---|---|---|
<package> | string | Yes | The package name to remove. |
Options
None.
Behaviour
- Discovers
ashes.jsonby walking upward from the current directory (same discovery as other commands). - If no
ashes.jsonis found, the command fails with exit code 1. - If the package is not present in
dependencies, the command fails with exit code 1. - Removes the package from the
dependenciesobject and writes the file back. - If the
dependenciesobject becomes empty after removal, the field is omitted from the written JSON.
Exit Codes
| Code | Meaning |
|---|---|
0 | Dependency removed successfully. |
1 | No ashes.json found, missing package argument, package not in dependencies, or I/O error. |
Examples
ashes remove json-parser
# Removed json-parser from dependencies.ashes restore
Resolve and materialize a project's dependencies from the nearest ashes.json. (ashes install is retired.)
Synopsis
ashes restore [--registry <name-or-url>] [--frozen] [--offline]Options
| Name | Description |
|---|---|
--registry <r> | Registry to resolve registry dependencies against (name or URL; default from config). |
--frozen | Fail (ASH032/ASH033) if a fresh resolution would differ from the committed ashes.lock; never rewrite it. For CI. |
--offline | Never touch the network; trust ashes.lock and only verify its packages are in the cache. |
Behaviour
- Discovers
ashes.jsonby walking upward from the current directory. - Fetches and caches registry dependencies (resolving SemVer constraints across the transitive graph) and writes
ashes.lock; then validates path dependencies (a missing path or non-project fails withASH030/ASH031) and lists every resolved dependency with its namespace. - Each cached package's content is verified against the lock's
ash1:hash (ASH034on mismatch). build/run/testauto-restore when a project's lock is missing or a locked package is not cached (against the default registry). Useashes restoreexplicitly to target a specific registry, or with--frozen/--offline.
Examples
ashes restore --registry https://pkg.ashes-lang.org
# Resolved 2 dependencies into ashes.lock.ashes tree
Render the resolved dependency tree (project root → direct dependencies → their transitive dependencies, from ashes.lock). Path dependencies are shown as leaves.
ashes tree
# app
# └── Json 1.2.0
# └── Utf8 0.4.3ashes why
Show a path from a project root dependency to the named package, explaining why it is in the graph.
ashes why Utf8
# Json -> Utf8Project File (ashes.json)
The project file enables multi-module compilation and controls build settings.
Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
entry | string (file path) | Yes | — | Relative path to the entry-point .ash file. |
name | string | No | Filename stem of entry | Output binary name (without extension). |
sourceRoots | string array | No | ["."] | Directories searched when resolving import statements. |
include | string array | No | [] | Additional directories searched for imported modules. |
outDir | string | No | "out" | Directory where the compiled binary is written. |
target | string (enum) | No | OS default | Default back end target; overridden by --target on the command line. |
dependencies | object (string → string) | No | {} | Map of package names to version constraints. Recorded in v0.x but not yet resolved or fetched automatically. |
Example
{
"name": "myapp",
"entry": "src/Main.ash",
"sourceRoots": ["src"],
"outDir": "build",
"target": "linux-x64"
}Module Import Syntax
Within any .ash file in a project, modules can be imported with:
import ModuleName
import Namespace.ModuleName- Module names must start with an uppercase letter.
- Nested namespaces use dot notation; each component must start with an uppercase letter.
- Import statements are collected from anywhere in the file; idiomatic style is to place them before any expression code.
- Circular imports are detected and reported as an error.
Exit Code Summary
| Code | Meaning |
|---|---|
0 | Success. |
1 | Compilation error, runtime error, test failure, or concrete user/input error. |
2 | Usage / argument error (bad flag, conflicting options, or unknown command syntax). |
The exit code from ashes run is the compiled program's own exit code when compilation succeeds.
Validation Rules and Error Behaviour
| Condition | Error message / behaviour | Exit code |
|---|---|---|
| Unknown command | Help text printed | 2 |
| Unknown flag | Unknown argument. | 2 |
| Missing required compile/run input | Missing input file or --expr. | 1 |
| Missing required fmt path | Missing file or directory. | 1 |
| Input file not found | File not found: <path> | 1 |
| Input file has wrong extension | Input file must have .ash extension (or use --expr). | 1 |
--project combined with file/--expr | Cannot combine --project with input file or --expr. | 2 |
--target receives unknown value | Message indicating unknown target, e.g. Unknown target '<value>'. | 1 |
ashes.json missing entry field | Project file is missing required string field 'entry'. | 1 |
ashes.json entry file not found | Project entry file not found: <path> | 1 |
| Import cycle detected | Import cycle detected: A -> B -> A | 1 |
| Parse / type error in source | Diagnostic message | 1 |
ashes fmt given more or fewer than one path | Provide exactly one file or directory. | 2 |
ashes fmt path does not exist | Path not found: <path> | 1 |
ashes init when ashes.json exists | ashes.json already exists in this directory. | 1 |
ashes add without package argument | Missing package name. | 1 |
ashes add when no ashes.json found | No ashes.json found. Run 'ashes init' first. | 1 |
ashes remove without package argument | Missing package name. | 1 |
ashes remove when no ashes.json found | No ashes.json found. Run 'ashes init' first. | 1 |
ashes remove when package not a dependency | Package '<name>' is not a dependency. | 1 |
ashes restore when no ashes.json found | No ashes.json found. Run 'ashes init' first. | 1 |
Debug Mode
The --debug (or -g) flag instructs the compiler to embed debug information in the output binary for source-level debugging. The exact debug format is target-dependent.
Behaviour
| Aspect | Effect |
|---|---|
| Debug metadata | Debug information is emitted into the output binary; the exact sections and format depend on the target platform. |
| Optimization | Without an explicit -O flag, optimization defaults to -O0 for the most faithful single-stepping. An explicit -O1/-O2/-O3 is honored (no cap), so a profiled debug build matches the optimized binary's inlining. The DWARF stays valid at every level — the backend re-verifies the module after optimization when debug info is requested. |
| Compile summary | An extra Debug: yes line is printed in the ashes compile success output. |
| Target triple | --debug does not change the Windows LLVM target triple; the current implementation continues to target x86_64-pc-windows-msvc. |
Interaction with Optimization Levels
| User flags | Effective optimization |
|---|---|
--debug (no -O) | -O0 |
--debug -O0 | -O0 |
--debug -O1 | -O1 |
--debug -O2 | -O2 |
--debug -O3 | -O3 |
-O3 (no --debug) | -O3 (unchanged) |
Example
# Compile with debug info (defaults to -O0)
ashes compile --debug examples/hello.ash -o hello
# Compile with debug info and explicit -O1
ashes compile -g -O1 examples/hello.ash
# Run under debugger
ashes run --debug examples/hello.ashCompatibility Rules
Breaking Changes
The following changes would break existing users or tooling and must be treated as breaking:
- Removing a command or flag.
- Changing the meaning of an existing flag.
- Changing exit codes for existing conditions.
- Changing the format of the success output line for
ashes compile.
Non-Breaking Changes
The following changes are considered non-breaking:
- Adding new commands or flags.
- Adding new
--targetvalues. - Adding new fields to
ashes.json(with defaults). - Changing diagnostic or error message wording (not the exit code).
- Changing the visual styling of terminal output (colours, table borders).
