https://github.com/ericspencer00/resilient
Rust-based, self-healing, formal verification based Programming Language
https://github.com/ericspencer00/resilient
programming-language
Last synced: about 2 months ago
JSON representation
Rust-based, self-healing, formal verification based Programming Language
- Host: GitHub
- URL: https://github.com/ericspencer00/resilient
- Owner: EricSpencer00
- Created: 2025-07-30T22:18:06.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2026-04-18T04:34:31.000Z (2 months ago)
- Last Synced: 2026-04-18T04:40:22.719Z (2 months ago)
- Topics: programming-language
- Language: Rust
- Homepage: http://ericspencer.us/Resilient/
- Size: 2.23 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Security: SECURITY.md
- Roadmap: ROADMAP.md
- Agents: AGENTS.md
Awesome Lists containing this project
README

### A statically-typed, compiled language built for code that *cannot fail.*
*Self-healing live blocks. Z3-backed contracts. Signed certificates. `no_std` from the metal up.*
[](LICENSE)
[](CONTRIBUTING.md)
[](https://github.com/EricSpencer00/Resilient/issues)
[](https://ericspencer.us/Resilient/)
[**π Docs**](https://ericspencer.us/Resilient/) Β Β·Β
[**π Playground**](https://ericspencer.us/Resilient/playground/) Β Β·Β
[**π Get Started**](https://ericspencer.us/Resilient/getting-started) Β Β·Β
[**π§ Philosophy**](https://ericspencer.us/Resilient/philosophy) Β Β·Β
[**β‘ Performance**](https://ericspencer.us/Resilient/performance) Β Β·Β
[**π§ Memory Model**](https://ericspencer.us/Resilient/memory-model) Β Β·Β
[**π©Ί Examples**](https://github.com/EricSpencer00/Resilient-examples) Β Β·Β
[**π€ Contributing**](CONTRIBUTING.md)
---
> **Resilient is open source under the MIT license β contributions from humans *and* AI agents are first-class.**
Resilient is a statically-typed compiled language for **safety-critical embedded systems** β Z3-verified function contracts (`requires` / `ensures`) discharged at compile time, a `#![no_std]` runtime that cross-compiles to Cortex-M and RISC-V bare metal, and self-healing `live { }` blocks that recover from transient hardware faults. Compare it to [Rust embedded](https://ericspencer.us/Resilient/compare/rust-vs-resilient), [Ada / SPARK](https://ericspencer.us/Resilient/compare/ada-spark-vs-resilient), and [MISRA C](https://ericspencer.us/Resilient/compare/misra-c-vs-resilient), or read the [DO-178C](https://ericspencer.us/Resilient/standards/do-178c), [ISO 26262](https://ericspencer.us/Resilient/standards/iso-26262), and [IEC 62304](https://ericspencer.us/Resilient/standards/iec-62304) standards mappings.
## Trust model
Resilient treats AI-written code as **untrusted input** to a trusted
verifier β not as a participant in the proof. The compiler, Z3, and TLA+
re-derive every safety claim from the typed AST; nothing the LLM asserts
in a comment or message is taken at face value.
In short: the LLM is a *client* of the type system, not the prover.
- **[STRUCTURAL_ENFORCEMENT.md](docs/STRUCTURAL_ENFORCEMENT.md)** β
the boundary, what's structural, what's external, what we trust.
- **[EXPRESSIBLE_INVALID_STATES.md](docs/EXPRESSIBLE_INVALID_STATES.md)** β
the public registry of what Resilient *cannot yet* prevent
structurally, with a closing ticket per gap.
- **[VERIFICATION_LIMITS.md](docs/VERIFICATION_LIMITS.md)** β
RES-202: where verification's guarantees end and real-world
uncertainty begins.
If you've read a critique that says "this is just self-consistency, not
safety," start with the first link.
## Core Philosophy
Resilient is a statically-typed, compiled programming language designed from the ground up for extreme reliability in embedded and safety-critical systems. Its core philosophy is built on three pillars:
### Resilience
Failures are inevitable. Resilient treats them as expected events, not exceptions. The language provides built-in mechanisms for code to "self-heal" and continue execution, ensuring the system never enters a non-functional state.
### Verifiability
It shouldn't just work; it must be provably correct. Resilient integrates concepts from formal methods to allow developers to define and verify system invariants at compile time.
### Simplicity
The syntax is designed to be minimal and unambiguous, reducing the cognitive load on the developer and minimizing the surface area for bugs.
## Target Applications
- **Automotive**: Engine control units (ECUs), autonomous driving systems, braking systems.
- **Aerospace**: Flight control systems, drone autopilots.
- **Industrial Automation**: Robotic arms, safety controllers on manufacturing lines.
- **Medical Devices**: Infusion pumps, monitoring equipment.
## Safety Standards
Resilient is not a certified tool and does not claim DO-178C,
ISO 26262, or IEC 61508 conformance β tool qualification is a
multi-year effort that has not started. What the language does
provide is a set of features (formal contracts, re-verifiable
SMT-LIB2 certificates, signed manifests, `static-only` heap
enforcement, ASCII-only identifiers, deterministic execution)
that map directly to specific objectives in each standard and
reduce the evidence burden on the integrator. See the
[Certification and Safety Standards](https://ericspencer.us/Resilient/certification)
page for the concrete objective-by-objective mapping and the
honest list of gaps.
## Key Features
### The "Live" Block: Self-Healing Code
The cornerstone of Resilient is the live block. Any code within a live block is supervised by the Resilient runtime. If a recoverable error occurs within this block, the runtime will not panic or halt. Instead, it will reset the state of the block to its last known-good state and re-execute it.
```
// Example of a live block that handles division by zero
live {
let result = 100 / user_input;
println("Result: " + result);
}
```
### Formal Methods Lite: Invariants with assert
For the MVP, we introduce a simple form of formal verification using an enhanced assert macro. These assertions define critical system invariantsβconditions that must always be true.
```
// System invariant that must not be violated
assert(fuel_level >= 0, "Fuel level cannot be negative");
```
### Static Type Checking
Resilient includes static type checking to catch type errors before runtime. This helps prevent common errors and ensures more reliable code.
```
// Function with typed parameters
fn calculate_velocity(float distance, float time) {
return distance / time;
}
```
### Improved Error Handling
Resilient provides detailed error messages and has sophisticated error recovery mechanisms, especially within live blocks.
## Getting Started
The shipped CLI is **`rz`** β short for Resilient, matches the `.rz` source extension.
### Install
Pick the path that matches what you have. Each leaves `rz` on `$PATH`.
#### One-liner (recommended)
Downloads the latest release binary into `~/.rz/bin/rz` (no sudo needed):
```bash
curl -fsSL https://raw.githubusercontent.com/EricSpencer00/Resilient/main/scripts/install.sh | bash
```
Then add `~/.rz/bin` to `PATH` (the script prints the exact line for your
shell). For a system-wide install: `RZ_PREFIX=/usr/local sudo bash`.
Pin a version with `RZ_VERSION=v0.1.0 β¦`.
#### Pre-built binaries
Grab the archive matching your platform from the
[releases page](https://github.com/EricSpencer00/Resilient/releases),
extract `rz`, and put it on `PATH`:
```bash
TAG=v0.1.0 # see the releases page for the latest
TARGET=aarch64-apple-darwin # or x86_64-apple-darwin / *-unknown-linux-gnu
curl -fSL "https://github.com/EricSpencer00/Resilient/releases/download/${TAG}/rz-${TAG}-${TARGET}.tar.gz" \
| tar xz -C /usr/local/bin
rz --version
```
#### From source via cargo install
If you have Rust installed:
```bash
git clone https://github.com/EricSpencer00/Resilient.git
cd Resilient
cargo install --path resilient
rz --version
```
This puts `rz` in `~/.cargo/bin/rz` (already on `PATH` if cargo is configured
normally). Add `--features z3` for SMT-backed verification (requires
`brew install z3` or `apt-get install libz3-dev`).
#### Docker (RES-203)
A prebuilt image is published to GitHub Container Registry on every
tagged release. Pull + run without installing Rust:
```bash
docker run --rm ghcr.io/ericspencer00/resilient:latest --help
# Run a source file by mounting it in:
docker run --rm -v "$PWD":/work -w /work \
ghcr.io/ericspencer00/resilient:latest resilient/examples/hello.rz
```
The image is multi-arch (linux/amd64 + linux/arm64), built from `Dockerfile`
at repo root. Ships with the `--features z3` build so the SMT-backed
verifier works out of the box. Runs as an unprivileged `resilient` user
(UID 1001) β mount working directories with matching permissions if you
want the binary to write certificates / artifacts back.
### Hello, Resilient
```bash
cat > hello.rz <<'EOF'
fn main() {
println("Hello, Resilient!");
return 0;
}
main();
EOF
rz hello.rz
# Hello, Resilient!
```
### Running an example
The repo's `resilient/examples/` directory has dozens of working programs:
```bash
rz resilient/examples/sensor_monitor.rz
# With static type checking
rz --typecheck resilient/examples/sensor_monitor.rz
# With verification audit (shows static-vs-runtime contract coverage)
rz --audit resilient/examples/sensor_monitor.rz
```
For full mission-critical project demos β pacemaker, infusion pump, ABS
brake controller, traffic-light interlock, reactor coolant monitor, CAN
bus parser β see the dedicated companion repo:
β **[EricSpencer00/Resilient-examples](https://github.com/EricSpencer00/Resilient-examples)**
Each project there is a small, runnable program with its own README
explaining the safety property, the language features it exercises,
and the limitations or follow-up tickets.
### Running the REPL
```bash
rz
```
### Building from source without installing
If you'd rather not install β typical contributor workflow:
```bash
cargo build --release --manifest-path resilient/Cargo.toml
./resilient/target/release/rz resilient/examples/hello.rz
```
### SMT-backed verification (optional)
Resilient ships with a hand-rolled contract verifier that handles
constant folding, let-binding propagation, control-flow assumptions,
and inter-procedural chaining. For contracts beyond that subset
(e.g. universal tautologies like `x + 0 == x`), build with the
optional `z3` feature to get full SMT-backed proofs:
```bash
# macOS: brew install z3
# Linux: sudo apt-get install libz3-dev z3
rz --audit prog.rz # requires the binary built with --features z3
```
The audit report tags clauses proven by Z3 separately so users can
see what the SMT layer added.
### Verification certificates (RES-071)
Once Z3 has discharged a contract obligation, you can ask the driver
to dump the proof as an SMT-LIB2 file so a downstream consumer can
re-verify it under their own solver β without trusting the Resilient
binary:
```bash
rz --emit-certificate ./certs resilient/examples/cert_demo.rz # requires --features z3 build
```
One file is written per discharged obligation:
`./certs/____.smt2`. Each file is self-contained
(declares every free variable, pins call-site bindings, asserts the
negated goal, ends with `(check-sat)`). Feed it to stock Z3:
```bash
z3 -smt2 ./certs/ident_round__decl__0.smt2
# unsat β the proof: negation is unsatisfiable, so the original holds
```
Implies `--typecheck`. Without `--features z3`, no certificates are
emitted (the cheap folder isn't asked to produce them).
#### Signed certificates (RES-194)
Pass `--sign-cert ` alongside
`--emit-certificate ` to write a 64-byte Ed25519 signature to
`/cert.sig`. The signed payload is the byte-for-byte
concatenation of the `.smt2` files in the directory (sorted by
filename, joined with `\n`); the signature binds the certificate
set to the signer's key.
```bash
# Sign during emit:
rz -t --emit-certificate ./certs --sign-cert ~/.resilient-priv.pem src/main.rz
# Verify against the binary's embedded public key:
rz verify-cert ./certs
# Or against a custom public key (e.g. a rotated / test key):
rz verify-cert ./certs --pubkey ./trusted-pub.pem
```
Exit codes from `verify-cert`: `0` = valid signature, `1` =
tampered / wrong key, `2` = usage error (missing directory, etc.).
The committed public key lives at `resilient/src/cert_key.pem` and
is baked into the binary via `include_str!`. Key management (the
corresponding private key + rotation) is a human concern β the
signing key is NOT committed. See the ticket's Notes for the
rotation-follow-up plan.
The PEM format is a minimal `-----BEGIN ED25519 {PUBLIC,PRIVATE}
KEY-----` envelope around 64 hex chars (32 raw bytes). A tiny
helper is provided inside the `cert_sign` module; external tools
that want to generate a compatible keypair can use any Ed25519
library and format the output identically.
#### Certificate manifest (RES-195)
Every `--emit-certificate ` run also writes a
`manifest.json` index:
```json
{
"program": "fib.rz",
"obligations": [
{
"fn": "fib",
"kind": "ensures",
"idx": 0,
"cert": "fib__ensures__0.smt2",
"sha256": "<64 hex>",
"sig": "<128 hex>"
}
]
}
```
- `sha256` is always present and always over the `.smt2` file's
bytes β consumers can detect tampering without holding any
cryptographic key.
- `sig` is present only when `--sign-cert` was passed; it's an
Ed25519 signature over THIS cert's bytes (not the batch). The
top-level `cert.sig` from RES-194 still covers the whole
payload β both are written on signed runs so either can be
used for verification.
The `verify-all` subcommand re-checks every obligation:
```bash
# Fast cryptographic-only pass:
rz verify-all ./certs
# With a custom public key (for rotated / test keys):
rz verify-all ./certs --pubkey ./trusted-pub.pem
# Extra: re-run Z3 on each cert (if the `z3` binary is on PATH):
rz verify-all ./certs --z3
```
Output is a one-row-per-obligation table with `sha256`/`sig`/`z3`
columns (`ok`, `FAIL`, `-` = skipped). Exit 0 iff every checked
cell passes; exit 1 on any failure or missing file; exit 2 on
usage errors. Without `--z3`, the column is skipped β the
cryptographic checks alone are a strong regression signal.
### Embedded runtime (RES-075 + RES-097 + RES-098)
The sibling `resilient-runtime/` crate carves out the value layer
+ core ops in a `#![no_std]`-compatible form, ready for a
Cortex-M class MCU. RES-075 Phase A shipped the alloc-free
`Value::Int`/`Value::Bool` types; RES-097 verified the
cross-compile; RES-098 added an opt-in `alloc` feature for
`Value::Float` (always available β stack-only) and `Value::String`
(behind the feature).
```bash
# Host build, default features (alloc-free) β 11 unit tests
cd resilient-runtime
cargo build
cargo test
# Host build with alloc β 14 unit tests (adds Float + String coverage)
cargo build --features alloc
cargo test --features alloc
```
#### Verified cross-compile
`resilient-runtime` builds for the `thumbv7em-none-eabihf` target
(Cortex-M4F class MCU) in both feature configs:
```bash
rustup target add thumbv7em-none-eabihf
# Default (alloc-free) β Cortex-M4F has native i64 instruction
# support, no compiler_builtins shim needed.
cargo build --target thumbv7em-none-eabihf
cargo clippy --target thumbv7em-none-eabihf -- -D warnings
# With --features alloc, embedded-alloc 0.5 is pulled in.
# The lib does NOT pick a #[global_allocator] β that's the
# binary's responsibility (LlffHeap from embedded-alloc is the
# common choice for Cortex-M).
cargo build --target thumbv7em-none-eabihf --features alloc
cargo clippy --target thumbv7em-none-eabihf --features alloc -- -D warnings
```
Embedded users wire the allocator in their binary's `main()`:
```rust
use embedded_alloc::LlffHeap as Heap;
#[global_allocator]
static HEAP: Heap = Heap::empty();
fn main() -> ! {
// initialize HEAP with a fixed-size memory pool, then use
// resilient_runtime::Value::String / Float freely.
loop {}
}
```
The `resilient/` crate is unaffected β it stays a single-crate
project; `resilient-runtime/` is a separate Cargo project alongside
it. A future ticket can promote both to a workspace if there's a
real reason (shared profile config, cross-crate testing).
See [`resilient-runtime-cortex-m-demo/`](resilient-runtime-cortex-m-demo/)
for a buildable example that links the runtime with an
`embedded-alloc` global allocator on Cortex-M4F (RES-101). Run
`scripts/build_cortex_m_demo.sh` from the repo root to verify the
cross-compile; the demo is a build check, not a runtime
demonstration.
#### Sink abstraction for `println` (RES-180)
The runtime exposes a tiny `sink::Sink` trait β one method,
`write_str(&mut self, s: &str) -> Result<(), SinkErr>` β plus
a global `sink::println` / `sink::print` routed through the
currently-installed sink. Users wire a sink once at program
start with `sink::set_sink(&mut their_sink)`; subsequent
`println` calls thread text through it. On embedded this is
typically a UART / semihosting / ring-buffer writer; for tests
a memory-backed `BufSink` captures output for assertions.
Optional `std-sink` feature exports a `StdoutSink` convenience
type that forwards to `std::io::stdout()` for users who want
the old std-host behavior without rolling their own:
```rust
use resilient_runtime::sink::{set_sink, StdoutSink};
static mut STDOUT_SINK: StdoutSink = StdoutSink;
fn main() {
unsafe { set_sink(&mut STDOUT_SINK); }
resilient_runtime::sink::println("hello from the runtime").unwrap();
}
```
The core Sink / print / println surface is always available
β no feature flag needed. `StdoutSink` sits behind `std-sink`
because it pulls in `std`, which is incompatible with
`no_std` embedded deployments.
Thread-safety: the global sink pointer is held in an
`UnsafeCell` wrapped in a `Sync` newtype. Sound for embedded
bare-metal (single-core / single-thread). Tests serialize
via a shared `SINK_TEST_LOCK` (same pattern as RES-150's RNG
lock). Multi-threaded embedded use would need a
`critical-section` crate or a `spin::Mutex` β left for a
follow-up when the use case appears.
#### Code-size budget (RES-179)
CI runs `cargo bloat` against the release Cortex-M4F demo on
every push + PR via the `size-gate` workflow. The gate fails
if the `.text` section exceeds **64 KiB** (overridable via the
`SIZE_BUDGET_KIB` env var in `.github/workflows/size_gate.yml`).
Current measurement (release, `thumbv7em-none-eabihf`):
| Section | Size | % of budget |
| ------- | ---------- | ----------- |
| `.text` | **2.3 KiB** (~2 355 bytes) | **3.6 %** |
Plenty of headroom β the budget is deliberately generous per the
ticket Notes; tighten in a follow-up once we have a stable
baseline across releases. The top .text contributors today are
`compiler_builtins::mem::memcpy` (~31 %), the demo's own `main`
(~21 %), and `embedded_alloc`'s `dealloc` / `alloc` wrappers
(~12 % / ~11 % respectively) β everything else is single-digit
bytes.
Run locally:
```bash
scripts/check_size_budget.sh # default 64 KiB
SIZE_BUDGET_KIB=32 scripts/check_size_budget.sh # tighter budget
```
The script prints `cargo bloat`'s top-20 symbol table either
way, so a failing run attributes the regression without needing
to re-run anything.
#### `--features static-only` (RES-178)
For safety-critical projects that forbid dynamic allocation
entirely, the runtime crate exposes a mutually-exclusive
`static-only` feature. Under it, the reduced `Value` surface is:
| feature flags | Value::Int | Value::Bool | Value::Float | Value::String |
| ------------------------- | :--------: | :---------: | :----------: | :-----------: |
| (default) | β
| β
| β
| β |
| `--features alloc` | β
| β
| β
| β
|
| `--features static-only` | β
| β
| β
| β |
| `alloc + static-only` | *build fails: `compile_error!`* |
`static-only` is an assertion, not an enabler: setting it makes
any attempt to add a heap-bearing Value variant without
feature-gating it fail the build. The existing
`#[cfg(feature = "alloc")]` gates around `Value::String` (and
their future cousins for Array/Map when those land here) already
provide structural enforcement; `static-only` adds the intent
contract + the explicit mutex.
```bash
cd resilient-runtime
# Alloc-free build (same as default β feature is assertive).
cargo build --features static-only
cargo test --features static-only # 13 tests
# Prove the mutex:
cargo build --features "alloc static-only" # compile_error!
```
The `resilient/` CLI crate is NOT built with `static-only` β the
compiler itself needs alloc. The feature is runtime-only.
#### Cortex-M0 / M0+ / M1 thumbv6m (RES-177)
The Armv6-M lower-end (Cortex-M0 class, e.g. RP2040's dual-M0+
cores or STM32F0) is the watch target for "did anything pull
in a dep that assumes M4F-only features?" β no FPU, no 32-bit
atomics, no DSP extensions. The runtime today uses **no
atomics** anywhere (RES-141's telemetry counters live in the
`resilient` CLI binary, not in `resilient-runtime`), so the
ticket's `#[cfg(target_has_atomic = "32")]` gating isn't
triggered today; the CI gate will catch any future regression
the moment a dep tries to pull in `AtomicU32`.
```bash
rustup target add thumbv6m-none-eabi
cd resilient-runtime
cargo build --target thumbv6m-none-eabi
cargo build --target thumbv6m-none-eabi --features alloc
cargo clippy --target thumbv6m-none-eabi -- -D warnings
```
`scripts/build_cortex_m0.sh` is the one-shot equivalent. The
`alloc` feature builds clean (embedded-alloc + linked_list_allocator
+ critical-section's M0 single-core backend all link). `Value::Float(f64)`
also compiles (soft-float via libgcc), but floats are slow on M0
β the ISA has no FPU, so every float op is a runtime library call.
Avoid floats on M0 when you can; stick to `Value::Int(i64)`.
#### RISC-V rv32imac (RES-176)
The runtime also cross-compiles to
`riscv32imac-unknown-none-elf` β the baseline ISA for HiFive,
GD32V, and ESP32-C3 class chips. Both the default (alloc-free)
and `alloc` feature sets build clean, and `embedded-alloc`'s
`linked_list_allocator` backend works on RISC-V without target
overrides.
```bash
rustup target add riscv32imac-unknown-none-elf
cd resilient-runtime
cargo build --target riscv32imac-unknown-none-elf
cargo build --target riscv32imac-unknown-none-elf --features alloc
cargo clippy --target riscv32imac-unknown-none-elf -- -D warnings
```
Run `scripts/build_riscv32.sh` from the repo root to execute all
three steps in one shot. CI gates the RISC-V build via the
`embedded` workflow (`.github/workflows/embedded.yml`) alongside
the Cortex-M job.
There's no separate RISC-V demo crate yet β one embedded demo
(RES-101's Cortex-M4F) is enough to exercise the `#[global_allocator]`
wiring; adding a second target would multiply maintenance for
zero new coverage.
### Available Examples
All in `resilient/examples/`. Each ships with a `.expected.txt`
sidecar so the smoke tests can verify they still produce the
documented output.
- `hello.rz` β `println("Hello, world!");`
- `minimal.rz` β smallest working program with a top-level return
- `int_math.rz` β arithmetic + integer operators
- `sensor_monitor.rz` β `live { }` block reading a synthetic sensor
- `self_healing.rz` β recovery after a transient error inside a live block
- `nested_array_demo.rz` β multi-dimensional array indexing/assignment
- `cert_demo.rz` β minimal program whose contract Z3 can discharge,
used by `--emit-certificate` (RES-071)
- `imports_demo/` β multi-file import resolution
- `file_io_demo.rz` β round-trip through `file_read` / `file_write`
(RES-143)
**Safety considerations for `file_read` / `file_write` (RES-143):**
the CLI has ambient filesystem authority and these builtins inherit
it with no sandboxing. Run untrusted Resilient programs inside a
chroot or container if you care about what they can touch. The
`resilient-runtime` sibling crate (used by embedded targets) has no
builtins table and therefore no file I/O surface β it stays
no_std-clean.
### Debugging
`--dump-tokens ` prints the lexer's token stream β one
`line:col Kind("lexeme")` per line, ending with `Eof` β and
exits. Useful when a parser error points at a mystery token and
you want to see what the scanner actually emitted, without
editing source (RES-112). Mutually exclusive with `--lsp`.
```sh
rz --dump-tokens resilient/examples/hello.rz
# 2:1 Function("fn")
# 2:4 Identifier("main")("main")
# 2:8 LeftParen("(")
# ...
# 6:1 Eof("")
```
`--dump-chunks ` compiles the program to VM bytecode and
prints a human-readable disassembly of every chunk β `main` plus
each user function β with constants, per-op offset/line/opname
columns, and absolute jump targets (RES-173). The output reflects
the RES-172 peephole pass, so what you see is what runs.
```sh
rz --dump-chunks resilient/examples/hello.rz
# === main ===
# constants:
# const[0] = "Hello, Resilient world!"
# code:
# 0000 L2 Const 0 ; const[0] = "Hello, Resilient world!"
# 0001 L2 Call 0 ; -> println
# 0002 L2 Return
```
Mutually exclusive with `--dump-tokens` and `--lsp`. The output
format is stable β external tools are welcome to parse it; the
disassembler module comment documents the exact column contract.
### Formatter
`rz fmt ` pretty-prints a Resilient source file in
canonical style (4-space indent, brace-on-same-line, contracts
indented under the function signature). By default it prints to
stdout; pass `--in-place` to overwrite the file.
```bash
rz fmt resilient/examples/hello.rz # print to stdout
rz fmt --in-place src/main.rz # overwrite
```
The formatter refuses to touch input with parse errors (exits 1).
It is a structural round-trip β comments are not preserved today;
only run it on code you're willing to re-attach comments to by
hand. See [Tooling Reference](https://ericspencer.us/Resilient/tooling#formatter)
for the full contract.
### REPL Commands
- `help` - Show help message
- `exit` - Exit the REPL
- `clear` - Clear the screen
- `examples` - Show example code snippets
- `typecheck` - Toggle type checking
### Randomness (RES-150)
The `random_int(lo, hi)` and `random_float()` builtins are backed
by **SplitMix64**, a tiny deterministic PRNG. The seed is either
pinned with `--seed ` (for reproducible runs) or derived from
the monotonic clock at startup and echoed to stderr as
`seed=` so a failing run can be replayed verbatim.
**These are NOT cryptographic.** Do not use `random_*` for key
material, session tokens, salts, nonces, or anything an attacker
could exploit if guessed. SplitMix64 is chosen for determinism and
small code size (β15 LOC, zero dependencies), not unpredictability.
When the language grows a cryptographic-grade primitive it will
live under a separate name with the appropriate guarantees.
## Editor & IDE Support
### Visual Studio Code
Install the [Resilient extension](https://marketplace.visualstudio.com/items?itemName=fromamerica.resilient-vscode) from the VS Code Marketplace for syntax highlighting, diagnostics, hover information, go-to-definition, and one-click file execution.
\`\`\`bash
# Or install from command line:
code --install-extension fromamerica.resilient-vscode
\`\`\`
**Features:**
- Syntax highlighting with TextMate grammar
- Real-time diagnostics (parse errors, type errors, contract violations)
- Language server protocol (LSP) support: hover types, completion, go-to-definition, find references
- One-click "Run Resilient File" button
**Setup:** The extension auto-detects the \`rz\` binary on \`$PATH\`. If \`rz\` is elsewhere, configure \`resilient.serverPath\` in settings.
### GitHub Syntax Highlighting
\`.rz\` files are recognized and highlighted on GitHub as of the [Resilient registration in Linguist](https://github.com/github-linguist/linguist). The VS Code extension grammar powers the coloring.
### Other Editors
Resilient supports LSP, so any editor with LSP client support (Vim, Neovim, Emacs, Sublime, etc.) can integrate the language server:
\`\`\`bash
# Start the LSP server:
rz --lsp
# Then point your editor's LSP client to this process.
\`\`\`
See [docs/lsp.md](docs/lsp.md) for editor-specific setup instructions.
## Performance
Run `cargo bench --manifest-path resilient/Cargo.toml` to benchmark the
tree-walker interpreter on three representative workloads (recursive
`fib(25)`, bubble-sort, and string concatenation). Results are saved to
`resilient/target/criterion/`; a captured baseline lives at
[`benchmarks/baseline.txt`](benchmarks/baseline.txt).
## Syntax Requirements
See the [SYNTAX.md](SYNTAX.md) file for detailed syntax requirements and examples. Key points:
- Function parameters carry explicit types; zero-parameter functions use `fn name()`
- Static variables maintain state between function calls
- Live blocks provide self-healing capabilities
- Assertions validate system invariants
## Project Status
Active development happens one ticket at a time. See [ROADMAP.md](ROADMAP.md)
for the goalpost ladder and [GitHub Issues (closed)](https://github.com/EricSpencer00/Resilient/issues?q=is%3Aissue+is%3Aclosed) for
the full ledger. Each commit of the form `RES-NNN: summary` closes one ticket.
### What works today
- Functions (with and without parameters), forward references
- `let` and `static let` bindings, reassignment
- Arithmetic, comparison, logical, bitwise, and shift operators
- Prefix `!` and `-`
- Hex (`0xFF`) and binary (`0b1010`) integer literals with `_` separators
- Block `/* */` and line `//` comments
- `if` / `else`, `while` (with runaway guard)
- `live { }` self-healing blocks with retry
- `assert(cond, msg)` with operand values in the error
- Built-ins: `println`, `print`, `len`, `abs`, `min`, `max`, `sqrt`,
`pow`, `floor`, `ceil`
- Clean `line:col:` error diagnostics
- 50+ passing tests covering lexer, parser, typechecker, interpreter,
and example programs (golden file sidecars in `resilient/examples/`)
- Zero panic paths in the parser or lexer β every error is recoverable
### Performance (RES-106)
A representative workload: fib(25), 242,785 recursive calls,
on Apple M1 Max. See `benchmarks/RESULTS.md` for the full
table including Python/Node/Lua/Ruby and the bench scripts.
| backend | fib(25) median | vs interp |
|--------------------------|----------------|-----------|
| Resilient (interp) | 406.7 ms | 1Γ |
| Resilient (VM, RES-082) | 33.7 ms | 12Γ |
| Resilient (JIT, RES-106) | **2.8 ms** | **145Γ** |
| Rust (native -O) | 2.0 ms | 204Γ |
The Cranelift JIT (`--features jit --jit`) is **~12Γ faster
than the bytecode VM** and within **~1.4Γ** of native Rust on
this workload, beating Lua (7.1 ms), Python 3 (32.5 ms),
Node.js (62.8 ms), and Ruby (71.2 ms). Compile time is
included in the measurement (amortized across the ~242k
calls); for one-shot arithmetic the VM is the right backend.
### What's next
- G4 (full source spans with snippets / carets)
- G5 (replace hand-rolled lexer with `logos`)
- G6 (one canonical AST, retire the unwired `parser.rs`)
- G7 (real type checker: inference, unification, exhaustiveness)
- G8βG10 (function contracts, symbolic assert, live-block invariants)
- G11+ (stdlib, structs, pattern matching, cranelift backend, LSP,
`no_std`, self-hosting)
### Self-hosting progress (G20)
G20 is a long arc. The first milestone is a Resilient program
that can lex Resilient source.
- **RES-196** β [`self-host/lex.rs`](./self-host/lex.rs): a byte-
level lexer for a restricted subset of the language, written
in Resilient itself. Recognizes identifiers, integer + string
literals, the `fn` / `let` / `return` / `if` / `else` / `while` /
`true` / `false` keywords, single-char punctuation,
single-char operators, the two-char comparison / logical
operators, and `//` line comments. Whitespace-skipping with
line / column tracking.
Run it: `./self-host/run.sh` (diffs output against
[`self-host/hello.tokens.txt`](./self-host/hello.tokens.txt)).
Not in CI β informative only until the self-hosted toolchain
becomes load-bearing. See the source file's top-comment for
the feature gaps (multiline strings, block comments, `live`
contracts, float / bytes literals) and the parser workarounds
the prototype needed to land today.