A compiler toolchain for Ion with a C code generation backend. ion-compiler emits human-readable C; ion-build transpiles, compiles with GCC or Clang, and links the runtime into an executable.
Ion is a systems programming language with:
- Move-only ownership, no GC
- Stack-only, no-escape references (
&T,&mut T) - Channels-only concurrency with OS threads and structural
Sendchecking - C backend: Ion is transpiled to human-readable C, then compiled with a C compiler
Brief summary; see ION_SPEC.md for the full language reference.
- Ownership: move by default; single owner per value; use-after-move is a compile error
- Borrowing:
&Tand&mut Tare stack-local; references cannot escape the function (no return, no struct fields, no channels, nospawn) - Types: primitives, structs, enums (tuple and struct variants), generics,
[T; N],[]T,Box<T>,Vec<T>,String - Control flow:
if/while(bool conditions),loop { },break/continue,for x in exproverVec<T>,[T; N], orString(bytes asu8),matchwith guards,defer - Concurrency:
channel<T>()returns(Sender<T>, Receiver<T>);send(&tx, v)andrecv(&mut rx);spawn { ... }with structuralSend - FFI:
extern "C"blocks, raw pointers*T, calls requireunsafe - Stdlib:
stdlib/io.ion,stdlib/fmt.ion,stdlib/fs.ion, andstdlib/result.ion
Known limitations: ION_SPEC.md section 10.3.
| Resource | Contents |
|---|---|
| ION_SPEC.md | Language semantics, grammar, stdlib contracts |
| docs/BETA.md | Beta subset, compatibility policy, and platform support |
| docs/ABI.md | Runtime ABI notes for generated C and stdlib types |
| CONTRIBUTING.md | Build, test, lint, and PR expectations |
| CHANGELOG.md | Release notes by month |
| tests/README.md | Integration test catalog |
| examples/ | Runnable example programs |
- Rust 1.96.0 (see
rust-toolchain.toml;rustup updateif your toolchain is older) - A C compiler: GCC or Clang (on Windows, use MinGW GCC for generated C; MSVC is not the primary target)
- Git Bash on Windows for
tests/test_runner.sh
cargo build --releaseThis builds ion-compiler, ion-build, and ion-lsp. Install into your Cargo bin directory:
cargo install --path . --bin ion-compiler --bin ion-buildBinaries: target/release/ion-compiler, target/release/ion-build, target/release/ion-lsp (.exe on Windows).
Ion has a VS Code / Cursor extension that provides:
- Syntax highlighting
- Real-time diagnostics (syntax, import, and type errors; multiple independent type errors per file)
- Hover: variable types at use sites and
letbinding identifiers; symbol signatures and attached//doc prose at definitions and qualified imports - Completion: prefix-filtered keywords, builtins, and file symbols
- Go to definition: variables, function calls, and user-defined methods; imported
mod::funcopens the module file - Find references, document outline, signature help, semantic tokens
- Workspace refresh when watched
.iondependencies change on disk
Full LSP feature list: ION_SPEC.md section 10.2.
Limitations: built-in methods (Vec::push, etc.) and type names in annotations do not go to definition. Full list in ION_SPEC.md section 10.3.
Installation:
-
Build the LSP server:
cargo build --release --bin ion-lsp
-
Install the extension from the
ion-vscodedirectory:cd ion-vscode npm install npm run compile npx @vscode/vsce package --allow-missing-repository code --install-extension ion-language-0.1.0.vsixOn Cursor, use
cursor --install-extension ion-language-0.1.0.vsixinstead ofcode. -
Workspace settings (
.vscode/settings.json) pointion.lspPathattarget/release/ion-lsp.exe.
Packaging (local install, no marketplace publish):
cd ion-vscode
npm install
npm run compile
npx @vscode/vsce package --allow-missing-repository
cursor --install-extension ion-language-0.1.0.vsixFrom the repository root (uses root ion.toml):
cargo build --release --bin ion-build
.\target\release\ion-build.exe build
.\target\hello_world.exeion build transpiles, compiles generated C, links the runtime, and writes the executable under target/ by default.
Source: examples/hello_world_safe/hello_world_safe.ion. For a minimal FFI example without stdlib, see examples/hello_world/hello_world.ion.
For codegen inspection, integration test workflows, or debugging generated C, use ion-compiler directly (see ION_SPEC.md section 10.1):
./target/release/ion-compiler examples/hello_world/hello_world.ion
gcc examples/hello_world/target/hello_world.c runtime/ion_runtime.c -o hello_world \
-I. -I.. -Iruntime -I../runtime -lpthread
./hello_worldThe integration harness (tests/test_runner.sh) calls ion-compiler and gcc this way. Application development should use ion-build instead.
ion-build discovers ion.toml by walking up from the current directory. Required fields: name, main, output. Common optional fields: mode (single or multi), out_dir (default target), cflags, ldflags, stdlib_paths, emit_in_source.
Root ion.toml builds examples/hello_world_safe/hello_world_safe.ion. Each example lives in its own directory under examples/ with an ion.toml manifest. Use --manifest path when cwd is not the example directory:
cd examples\spawn_channel
..\..\target\release\ion-build.exe build
.\target\spawn_channel.exeFFI programs that rename C symbols (for example recv_sys) set compile-time -D flags in cflags, not ldflags. See examples/http_server/ion.toml.
Multi-file mode (mode = "multi" in ion.toml) transpiles each module to .c/.h, compiles objects, and links one executable. Artifacts default to out_dir (usually target/), not the source tree.
cd examples\data_lib
..\..\target\release\ion-build.exe build
.\target\data_lib.exeFor manual multi-file codegen in the source directory (no ion-build), use ion-compiler --mode multi --output NAME main.ion. See examples/data_lib/README.md.
Each example is a subdirectory of examples/ with ion.toml. Build with ion-build from that directory; generated C and executables go under target/ (not committed).
Build and run:
cd examples\spawn_channel
..\..\target\release\ion-build.exe build
.\target\spawn_channel.exeOn Linux or macOS, use ./target/release/ion-build and drop .exe. Windows channel/spawn builds add -lws2_32 automatically.
| Directory | What it demonstrates |
|---|---|
| hello_world/ | Minimal FFI write() to stdout (no stdlib) |
| hello_world_safe/ | stdlib io module; also built by root ion.toml |
| minimal/ | Smallest valid program |
| spawn_channel/ | spawn with cross-thread channels |
| channel_worker/ | Channel worker |
| showcase/ | Mixed language features |
| access_log/ | Log parsing, spawn, channels, fmt/io |
| http_server/ | Sockets FFI, spawn per client, stdin quit to stop; see http_server/README.md |
| text_summary/ | fs read, string iteration, counts |
| todo_demo/ | Interactive todo list (Vec of structs, stdin); see todo_demo/README.md |
| data_lib/ | Multi-module library; see data_lib/README.md |
.
├── .cursor/skills/ # Cursor agent skills
├── .github/ # CI workflows
├── src/
│ ├── bin/ # ion-build, ion-lsp
│ ├── lexer/ # Tokenizer
│ ├── parser/ # AST construction
│ ├── ast/ # AST node definitions
│ ├── compiler/ # Module resolution, import paths
│ ├── build/ # ion.toml, ion-build driver, C toolchain
│ ├── tc/ # Type checker (safety, visibility, qualified names)
│ ├── ir/ # Intermediate representation
│ ├── cgen/ # C code generator
│ └── lsp/ # Language server
├── runtime/ # C runtime sources and headers
├── stdlib/ # Standard library modules
├── ion-vscode/ # VS Code / Cursor extension
├── examples/ # Example Ion programs
└── tests/ # Test programs
Unit tests:
cargo testIntegration tests (use Git Bash on Windows, not WSL):
cd tests && ./test_runner.shThe runner loads tests/test_expectations.tsv (exit codes, error patterns, codegen checks) and runs each entry. Add a new positive test with one .ion file plus one manifest line. See tests/README.md.
cargo clippy -- -D warningscargo fmt --checkMIT