A source-to-source transpiler from Ion to C. Ion is transpiled to human-readable C, then compiled with a C compiler.
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),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.2.
| Resource | Contents |
|---|---|
| ION_SPEC.md | Language semantics, grammar, stdlib contracts |
| 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 --releaseOr install into your Cargo bin directory:
cargo install --path . --bin ion-compilerThe binary will be at target/release/ion-compiler (or target/release/ion-compiler.exe on Windows).
Ion has a VS Code / Cursor extension that provides:
- Syntax highlighting
- Real-time diagnostics (syntax and type errors)
- Hover: variable types at use sites and
letbinding identifiers; symbol docs at fn/struct/enum definitions - Completion: keywords, builtins, and file symbols
- Go to definition: variables, function calls, and user-defined methods; imported
mod::funcopens the module file
Limitations: built-in methods (Vec::push, etc.) do not go to definition; completion has no prefix filtering. Full list in ION_SPEC.md section 10.2.
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.vsix# Compile Ion to C
./target/release/ion-compiler examples/hello_world.ion
# Compile C to executable (from project root)
gcc examples/hello_world.c runtime/ion_runtime.c -o hello_world \
-I. -I.. -Iruntime -I../runtime -lpthread
# Run
./hello_worldSource: examples/hello_world.ion. For stdlib-based I/O, see examples/hello_world_safe.ion.
Step 1: Compile Ion to C
./target/release/ion-compiler input.ionThis generates input.c in the same directory as the source file.
Step 2: Compile C to Executable
The generated C code requires the Ion runtime library:
gcc input.c runtime/ion_runtime.c -o input -I. -I.. -Iruntime -I../runtime -lpthreadRequired flags:
input.c- generated C fileruntime/ion_runtime.c- Ion runtime (when running from project root)-I. -I.. -Iruntime -I../runtime- include paths for runtime headers-lpthread- pthread library (required for channels and spawn)-o input- output executable name
Step 3: Run
./inputIf your Ion program uses FFI names that conflict with Ion keywords (recv, send), add -D flags when linking:
gcc http_server.c runtime/ion_runtime.c -o http_server \
-I. -I.. -Iruntime -I../runtime -lpthread \
-Drecv_sys=recv -Dsend_sys=send -Dclose=closesocket -lws2_32On Linux or macOS, omit -lws2_32 and -Dclose=closesocket. ion_net_init() is a no-op outside Windows.
./target/release/ion-compiler --mode multi --output myprogram main.ionThis parses imported modules, generates .c and .h per module, compiles object files, and links with the runtime. The --output flag sets the executable name (defaults to the main module name). Multi-file mode handles compilation and linking; you do not need to run gcc manually.
Top-level examples/*.ion files each have a checked-in merged examples/*.c codegen snapshot. Regenerate after compiler codegen changes:
for f in examples/*.ion; do ./target/release/ion-compiler "$f"; done
./target/release/ion-compiler examples/text_summary/text_summary.ionTop-level single-file examples (including channel_worker.ion) commit a merged .c snapshot next to the .ion. The text_summary/ subdirectory also commits one .c (it needs sample.txt). Multi-file examples/data_lib/ keeps only .ion sources; see examples/data_lib/README.md for build output (.c/.h generated in place, not committed).
Compile and run any single-file example:
./target/release/ion-compiler examples/spawn_channel.ion
gcc examples/spawn_channel.c runtime/ion_runtime.c -o spawn_channel \
-I. -Iruntime -lpthread -lws2_32 # omit -lws2_32 on Linux/macOS
./spawn_channelFor http_server.ion, add -Drecv_sys=recv -Dsend_sys=send when linking.
| File | What it demonstrates |
|---|---|
| examples/hello_world.ion | Minimal FFI write() to stdout |
| examples/hello_world_safe.ion | stdlib io module |
| examples/spawn_channel.ion | spawn with cross-thread channels |
| examples/http_server.ion | Sockets, FFI, concurrent clients via spawn |
| examples/showcase.ion | Mixed language features: tuples, +=, push_byte, spawn/channels |
| examples/access_log.ion | Log parsing, loop/break, match guards, spawn, channels, fmt/io |
| examples/minimal.ion | Smallest valid program |
| examples/channel_worker.ion | Channel worker: spawn sums jobs from a channel |
| examples/text_summary/text_summary.ion | fs file read, string iteration, line/word/byte counts |
| examples/data_lib/main.ion | Multi-module library (catalog.ion); see data_lib/README.md |
Build data_lib (multi-file; codegen is ephemeral, not in git):
cd examples/data_lib
../../target/release/ion-compiler --mode multi --output data_lib main.ion
./data_lib # or data_lib.exe on Windows.
├── src/
│ ├── lexer/ # Tokenizer
│ ├── parser/ # AST construction
│ ├── ast/ # AST node definitions
│ ├── compiler/ # Compilation driver (module resolution, cycle detection)
│ ├── tc/ # Type Checker (safety checks, visibility, qualified names)
│ ├── ir/ # Intermediate representation
│ └── cgen/ # C code generator
├── runtime/ # C runtime headers
├── 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 warningsMIT