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 stable (see
rust-toolchain.toml) - 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.
Each example has a matching examples/*.c checked in as a compiler-output snapshot (ownership, spawn, channel lowering, bounds checks). Those files are verbose: importing stdlib or other modules inlines merged C for those dependencies. Ion targets GNU C (GCC/Clang), not strict ISO C or MSVC. Regenerate after codegen changes:
for f in examples/*.ion; do ./target/release/ion-compiler "$f"; doneCompile and run any example with the same pattern as the quick start above. For 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 |
.
├── 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