KernRift

A self-hosted systems language compiler with a target-independent IR backend. Self-compiles on all 8 hosted targets — Linux, macOS, Windows, Android on x86_64 and ARM64 — and cross-compiles bare-metal for RISC-V 32, Xtensa and freestanding x86_64/ARM64, including direct-boot ESP32 images, Linux kernel modules, and a from-scratch x86_64 reset-vector image. No Rust, no C, no LLVM. Fat binaries by default.

KernRift is a programming language created by Pantelis Christou.

$ krc hello.kr -o hello.krbo
$ kr hello.krbo
Hello, World!

KernRift is a self-hosting systems language compiler written entirely in KernRift — ~304K tokens of source across 25 files, plus a 19-module standard library. The compiler ships with a target-independent IR backend: AST lowers to a linear three-address intermediate representation over unbounded virtual registers (not SSA — named variables reuse one vreg across assignments, so no phi nodes are ever built), liveness analysis runs, a graph-coloring register allocator with Briggs/George copy coalescing assigns physical registers, an optimizer does constant folding / DCE / CSE / LICM and an AST-level function inliner with cost-aware rotation-shape detection, and dedicated emitters produce native x86_64, AArch64, RISC-V 32 (RV32IMC) and Xtensa LX6 machine code. No Rust, no C, no LLVM, no external assembler — the compiler emits raw machine bytes directly. By default, krc produces BCJ+LZ-Rift-compressed fat binaries containing 8 platform slices — Linux, Windows, macOS, and Android, each with x86_64 and/or AArch64 native code. The compiler self-hosts on all 8 targets; CI verifies bootstrap fixed point and runs 1236 tests on every push. Recent work: v2.9.0 is a bare-metal release — six sub-projects (--target=none, --emit=image, compiler-emitted entry stubs via --stack-top, an arm64 Linux Image header, --emit=uefi, and a from-scratch x86_64 --reset-vector image booting real→protected→long mode with no GNU as/ld/objcopy) plus eight defect fixes and a correction of 17 sites that incorrectly called the IR SSA. Everything bare-metal is QEMU on one machine, emulated — no real hardware, no vendor firmware, and Secure Boot is measured incompatible; the boot gate has 59 legs and runs in CI on every push, including on a native ARM64 runner. Earlier v2.8.33 fixed a silent ARM64 miscompile of 32-bit rotations (present in v2.8.26-v2.8.32, and so affecting SHA-2/MD5/ChaCha-style code), made every backend abort on an unhandled IR opcode rather than emit nothing, and added an x86_64 XMM register class worth 3.2× on mandelbrot. Earlier v2.8.25+ added eight codegen peepholes (LEA-immediate, LEA[base+idx×scale], 3-operand IMUL, CMP-with-immediate, 32-bit ROR pattern recognition, w32-clean mask elimination, FFMA fusion, and a cost-aware rotation-shape inliner) that dropped sort runtime 29 % and sha-256 29 % vs v2.8.24, plus shrunk the self-host binary 10 %. Earlier v2.8.23 fixed three IR-emitter memory leaks that dropped peak self-compile RSS by 96–99 % (single-arch 806 MB → 33 MB; fat 6.3 GB → 87 MB), making fat self-compile feasible on a 4 GB Pi 400. Kernel-first primitives include device blocks for typed MMIO, load/store/vload/vstore pointer builtins, slice parameters [T] name with .len, static and struct arrays, inline assembly, signed comparisons, atomic operations, bitfield operations, and --freestanding mode.

Self-Hosting Compiler

KernRift compiles itself. The compiler is ~304K tokens of KernRift across 25 source files, plus 19 stdlib modules. It achieves a bootstrap fixed point — compiling itself twice produces bit-identical binaries, verified on all 8 platform targets (Linux x86_64/ARM64, macOS ARM64/x86_64, Windows x86_64/ARM64, Android ARM64/x86_64) with 1236 tests passing on every CI run. No LLVM, no Rust, no C, no external assembler — just KernRift all the way down.

Stage Input Output Verified
krc → krc2 ~63,500 lines (.kr) ~1.12 MB native ELF (IR, default) / ~1.68 MB (legacy)
krc2 → krc3 ~63,500 lines (.kr) identical output to krc2
krc3 → krc4 ~63,500 lines (.kr) identical output to krc3 krc3 == krc4 ✓
Self-compile time ~63,500 lines ~0.25s (legacy) / ~0.50s (IR + optimizer, default) ~3.5s fat binary (8 slices, ~4.9 MB) ✓
Cross-compile x86_64 host ARM64 + Windows PE + macOS Mach-O Tested on all platforms ✓
Fat binary any .kr file .krbo (8 slices, BCJ+LZ-Rift) Default output ✓

Bare Metal & Kernel Targets

Beyond the eight hosted slices, krc cross-compiles for embedded targets and for the Linux kernel. These paths emit machine code directly — still no LLVM, no assembler, no linker.

TargetInvocationOutputStatus
RISC-V 32 (RV32IMC) --arch=riscv32 --freestanding Bare-metal ELF Working ✓
Xtensa LX6 --arch=xtensa --freestanding Bare-metal ELF Working ✓
ESP32 (direct boot) --arch=xtensa --freestanding --target=esp32 esp-image for flash 0x1000 Hardware-validated ✓
Linux kernel module --emit=lkm Relocatable .ko Working ✓

ESP32. The emitted image is parsed and loaded by the chip's mask ROM straight from flash — no second-stage bootloader and no flash XIP, so the program is entirely RAM-resident: 127 KiB IRAM for code and 192 KiB DRAM for data, bss and stack, with 4 KiB reserved for the stack. Verified on an ESP32-D0WD-V3: the image boots and runs, and a single flipped payload byte is rejected by the ROM with csum err, confirming the checksum path is genuinely enforced. IRAM is 32-bit-access-only on this part, so byte-addressable data must live in DRAM — the compiler enforces that at compile time rather than letting it fault on the board.

Built with KernRift: CarRift. An open-source CAN-bus sniffer targeting a 2016 Opel Corsa, written entirely in KernRift and running bare-metal on an ESP32 through exactly this path (--arch=xtensa --freestanding --target=esp32) — no ESP-IDF, no FreeRTOS, no C toolchain. On the bench it drives a real CAN transceiver at 500 kbit/s with hardware-derived bit timing, MMIO device blocks and GPIO-matrix signal routing, and passes full frame loopback on silicon. Hooking it up to the live vehicle bus is the next step — it has not sniffed the actual car yet.

Current limits, stated plainly. The RISC-V 32 and Xtensa backends support integer code, control flow, string literals, static and stack data, inline assembly, function pointers and MMIO device blocks. In freestanding mode they do not yet support struct values (IR_ALLOC is unimplemented on that path — structs do work on hosted riscv32) or floating point. Both backends are 32-bit throughout and reject u64/i64 outright, which matters because u64 is the language default — embedded code uses uint32. Freestanding targets have no OS, so programs return from fn main() -> uint32 rather than calling exit(). Hosted x86_64 and ARM64 have no such restrictions.

v2.9.0: Bare-Metal Boot on x86_64 & ARM64

Six sub-projects take the compiler from "provably safe under static analysis" to programs that actually boot — under QEMU. --target=none is a new freestanding target (distinct from --freestanding on hosted arches): no libc, no host OS, every OS-bound construct refused at compile time, with print/println/f-strings/alloc routed through pluggable write/alloc providers (16550 UART, PL011, a bump heap) instead.

Sub-projectFlagWhat it does
Freestanding target --target=none No libc, no host OS; refuses raw syscalls, --legacy, and OS-bound --emit= modes
Raw image emission --emit=image Headerless flat binary; QEMU boot gate requires a computed sentinel on the wire, not just "didn't crash"
Entry stubs --stack-top Compiler-emitted stack setup — images are self-sufficient on both arches, no hand-written loader
arm64 Image header --image-header Prefixes the arm64 Linux Image header (64 bytes, magic 0x644d5241)
UEFI applications --emit=uefi PE32+ EFI apps that load and print under OVMF (x86_64) and AAVMF (arm64)
Reset-vector image --reset-vector 64 KiB x86_64 image booting from the CPU reset vector: 16-bit real → 32-bit protected → long mode, no GNU as/ld/objcopy/--defsym anywhere in the build

Everything bare-metal here is QEMU, on one machine, emulated. No real hardware, no vendor firmware. Secure Boot is measured incompatible — an MS-key OVMF refuses the identical artifact that runs unsigned. The boot gate (tests/target_none/boot_gate.sh) has 59 legs, 0 fail, 0 skip, and runs in CI on every push, including on a native ARM64 runner.

Also in v2.9.0: defect fixes that change behaviour — call_ptr silently dropped arguments 7+ and their side effects (now refused on both x86 backends); an unresolved extern fn produced a running binary with a wrong answer (now a hard error); --reset-vector=1-style =value flags were silently ignored, producing the wrong artifact class (now refused); and --debug silently emitted no array bounds checks on arm64 legacy codegen (now refused on that path).

Benchmarks vs. C and Rust

KernRift produces the smallest binaries and compiles 14-19× faster than gcc -O2 and 36-48× faster than rustc -O2. Runtime is now mixed against gcc -O2 rather than uniformly behind it: krc is 4.6× faster on sort (59 ms vs 272 ms), within 11% on mandelbrot and within 1.5× on sieve and matmul, but still 4-5× behind on sha256 and fib, where helper calls and call structure dominate. There is no auto-vectorization. That spread is the honest trade for a compiler that builds itself in under half a second. All measurements on AMD Ryzen 9 7900X, Linux 6.17, gcc 13.3, rustc 1.93, krc 2.8.33.

Compile Time

Benchmark krc gcc -O0 gcc -O2 rustc rustc -O2
Fibonacci (recursive, fib(40)) 1ms 25ms 43ms 71ms 80ms
Sort (bubble 10K ints) 2ms 28ms 32ms 91ms 100ms
Sieve (primes to 10⁶) 2ms 28ms 34ms 94ms 107ms
Matrix Multiply (200×200 int) 2ms 30ms 34ms 85ms 111ms
Self-compile krc (legacy / IR default) ~0.25s / ~0.50s N/A

Binary Size

Benchmark krc gcc -O0 gcc -O2 rustc rustc -O2
Fibonacci 296 B 15800 B 15800 B 3889248 B 3887792 B
Sort (bubble) 464 B 15960 B 15960 B 3905344 B 3888048 B
Sieve 464 B 16008 B 16008 B 3901200 B 3888144 B
Matrix Multiply 1104 B 15960 B 15960 B 3900272 B 3888488 B
Self-compiled compiler (x86_64 IR default / legacy) ~1.12 MB / ~1.68 MB N/A
Self-compiled fat binary (all 8 platforms) ~4.9 MB BCJ + LZ-Rift compressed

Runtime (median of 3)

Benchmark krc gcc -O0 gcc -O2 rustc rustc -O2
Fibonacci fib(40) 441ms 405ms 85ms 412ms 170ms
Sort (bubble 10K) 81ms 158ms 279ms 2854ms 48ms
Sieve (primes to 10⁶) 3ms 5ms 2ms 23ms 2ms
Matrix 200×200 25ms 16ms 4ms 133ms 4ms

krc's IR backend uses a graph-coloring register allocator (12 colors on x86_64, 23 on AArch64, 12 on RISC-V, 9 on Xtensa, Briggs/George copy coalescing with per-vreg colour ceilings, partial used-callee-save prologue, cross-register spill-reload peephole) plus constant folding / DCE / CSE / LICM, an AST-level function inliner with cost-aware rotation-shape detection, and codegen peepholes for LEA-immediate / LEA[base+idx×scale] / 3-operand IMUL / CMP-with-immediate / 32-bit ROR recognition / FFMA fusion. No auto-vectorization. v2.8.33 gave x86_64 a dedicated XMM register class, so f64 values live in xmm2-xmm15 instead of round-tripping through general-purpose registers on every operation — mandelbrot dropped 3.2×, from 1771 ms to 551 ms, closing the gap with gcc -O2 from 3.6× behind to 1.11×. It also widened the integer colour files (x86_64 6→12, AArch64 10→23) and, on Xtensa, 4→9, worth 1.90× on an int8 neural-network workload measured on ESP32 silicon. Compile time and binary size remain where krc excels most; runtime now ranges from beating gcc -O2 to roughly 5× behind it depending on the workload. Measurements on AMD Ryzen 9 7900X, gcc 13.3, rustc 1.93.

Self-Compilation Across Platforms

Self-compile = krc rebuilding its own ~304K-token source. Single-arch produces a native binary for the host architecture; fat binary bundles all 8 platform slices into one BCJ+LZ-Rift-compressed .krbo. v2.8.23 fixed three per-function memory leaks in the IR emitter and made the liveness scratch buffer reusable across basic blocks, dropping peak RSS ~96-99% vs v2.8.22 and making fat self-compile feasible on a 4 GB Raspberry Pi 400 (was OOM-bound). Peak RSS is the high-water mark of the compiler process; the resident set never grows beyond it during the run.

Platform / Device CPU / RAM Single Arch (time / peak RSS) Fat Binary (time / peak RSS)
Linux x86_64 (desktop) AMD Ryzen 9 7900X (12c/24t, 32 GB) 0.50 s / 39 MB 3.54 s / 108 MB
Windows 11 x86_64 (laptop) Intel Core Ultra 9 275HX (24c, 64 GB) 0.37 s / 45 MB 2.62 s / 114 MB
Linux ARM64 (Raspberry Pi 400) Cortex-A72 @ 1.8 GHz (4c, 4 GB) 4.53 s / 39 MB 32.54 s / 107 MB
Android ARM64 (Redmi Note 8 Pro) MediaTek Helio G90T (2× A76 + 6× A55, 6 GB) 2.76 s / 40 MB 19.68 s / 108 MB
Android ARM64 (Galaxy Z Fold 5) Snapdragon 8 Gen 2 (1×X3 + 4×A715/A710 + 3×A510, 12 GB) 0.98 s / 40 MB 7.35 s / 107 MB

All five rows are fresh v2.8.29 measurements (median of 3; time is the compiler's self-reported compile time, peak RSS is the process high-water mark). The device numbers fell sharply from the previous table because those rows predated the compiler’s optimization work — the Redmi Note 8 Pro dropped from 27.5 s to 2.76 s single-arch, the Pi 400 from 32.4 s to 4.53 s. The desktop is the only row that rose (0.40 s → 0.50 s): it was already current, and the compiler source grew ~16% when the RISC-V, Xtensa, ESP32 and LKM backends landed, so there is simply more of it to self-compile.

How Other Compilers Compare (Self-Build)

Compiler Self-Build Time Binary Size Source
KernRift krc (IR + optimizer, default) ~0.41s ~1.12 MB measured (Ryzen 9 7900X)
KernRift krc (legacy, --legacy flag) ~204ms ~1.68 MB measured (Ryzen 9 7900X)
TCC <1s (est.) ~100 KB bellard.org/tcc
Go toolchain ~1-3 min ~50 MB go.dev/rebuild
LLVM + Clang ~4-5 min ~50 MB OpenBenchmarking (Ryzen 9 7950X)
rustc (stage 2) ~6-8 min ~80 MB dtolnay/buck2-rustc-bootstrap
GCC (3-stage) ~20-90 min ~30 MB (cc1) OpenBenchmarking (220+ runs avg)

krc is not directly comparable to production compilers — it has a linear IR with constant-folding / DCE / CSE / LICM, an AST inliner with rotation-shape cost model, codegen peepholes (LEA-imm, LEA[base+idx×scale], 3-operand IMUL, CMP-imm, 32-bit ROR, w32-clean mask elim, FFMA fusion), and a graph-coloring register allocator with Briggs/George copy coalescing, but no auto-vectorizer and no external linker in the loop. The comparison shows where a short, self-contained compiler sits on the build-time spectrum. TCC is the closest analog. External data is from public benchmarks on comparable hardware; see linked sources.

~63,500 lines, ~1.12 MB self-compiled binary. 1236 tests. Bootstrap fixed point verified on all 8 targets (Linux, macOS, Windows, Android × x86_64, ARM64). Fat binary: 8 slices, BCJ+LZ-Rift compressed.

Self-Hosting

The compiler is written in KernRift and compiles itself. After a one-time bootstrap from the Rust bootstrap compiler, krc is fully self-sustaining. No external toolchain needed.

Universal Fat Binaries

By default, krc bundles 8 platform slices (Linux, Windows, macOS, Android × x86_64 + ARM64) into a single BCJ+LZ-Rift-compressed .krbo file. LZ-Rift compression uses 24-bit offsets, 65K hash tables, and lazy matching for arch-pair blobs. Use --arch=x86_64 or --arch=arm64 for a single-architecture native binary.

Device Blocks for MMIO

device UART0 at 0x3F201000 { Data at 0x00 : u32 } declares a hardware register set. Reads and writes to UART0.Data compile directly to volatile loads and stores with the right width, plus the appropriate memory barrier — mfence on x86_64, DSB SY on ARM64.

Clean Pointer Builtins

load8/16/32/64(addr) and store8/16/32/64(addr, val) replace the verbose unsafe { *(addr as uint32) = val } form. Volatile variants vload*/vstore* add memory barriers for MMIO. Same codegen, much cleaner to read.

Slice Parameters

fn foo([u8] data) takes a fat pointer (ptr, len). Inside the function, data.len reads the length and data is a plain pointer for indexing. Callers pass two arguments. Classic C (ptr, len) idiom with a nicer symbolic name.

Static & Struct Arrays

static u8[4096] page gives you a zero-initialized data-section buffer. Point[10] pts gives you a fixed array of struct instances with full pts[i].field syntax. Both work locally and at module scope.

Zero Dependencies

The compiler is a single static binary. It produces native ELF, PE, and Mach-O executables without cc, ld, ar, or any external tool. Each output binary is fully static — no libc, no dynamic linking, no runtime.

Cross-Platform Output

8 platform targets from any host: ELF (Linux + Android), PE/COFF (Windows), and Mach-O (macOS), each for x86_64 and AArch64. On Windows, install.ps1 sets up the toolchain and kr.exe runs fat binaries natively. KrboFat containers, AR archives, and KRBO portable objects.

Standard Library

19 modules (~4,700 lines) covering strings, I/O, math, formatting, memory management (bump-allocated arenas with guard pages, fixed-size pools with double-free detection — std/alloc.kr), dynamic arrays, hash maps, colors, fixed-point arithmetic, fast memory operations, framebuffer graphics, font rendering, UI widgets, time/clock access, structured logging, floating-point math, SHA-256 hashing, and raw socket networking. Import with import "std/string.kr" — the compiler resolves stdlib paths automatically via ~/.local/share/kernrift/.

VS Code LSP

First-class editor support via the KernRift VS Code extension (v0.2.3). Includes syntax highlighting, diagnostics from krc check, completions, hover documentation, and go-to-definition. Available on the VS Code Marketplace.

Import System

import "file.kr" brings in declarations from other source files with recursive dependency resolution and stdlib search paths. No more concatenation — the compiler resolves the dependency graph automatically.

Match Statements

match expr { val => { body } ... } for clean multi-way branching. Combined with enums, match provides exhaustive pattern handling for state machines and dispatch logic.

Methods & Short Aliases

fn Point.sum(Point self) attaches a method to a struct; call it with p.sum(). Short type aliases u8/u16/u32/u64 and i8..i64 are synonyms for the long forms. Nested struct access (a.b.c) works naturally.

Inline Assembly

asm("cli") or asm { "cli"; "sti" } emits raw machine instructions. Supports x86_64 privileged instructions (cr0/cr3, lgdt, lidt, wrmsr, cpuid, in/out) and ARM64 system instructions (msr, mrs, svc, wfi, dsb, dmb). Raw hex bytes for anything else.

Kernel Annotations

@naked functions skip prologue/epilogue — pure assembly bodies for ISR entry points. @noreturn marks diverging functions. @packed structs for hardware register layouts. @section(".text.init") for linker section placement.

Bitfield & Signed Ops

bit_get, bit_set, bit_clear, bit_range, bit_insert for hardware register manipulation. signed_lt/gt/le/ge for signed comparisons (the default <, >, <=, >= operators are unsigned). Stack size warnings at compile time.

Freestanding Mode

krc --freestanding disables the startup trampoline, auto-exit insertion, and OS-specific syscall wrappers — producing bare-metal code ready for kernel entry points, bootloaders, and embedded firmware.

Atomic Operations

Lock-free primitives for concurrent data structures: atomic_load, atomic_store, atomic_cas (compare-and-swap), atomic_add, atomic_sub, atomic_and, atomic_or, and atomic_xor. Compiled to native LOCK-prefixed instructions on x86_64 and LDXR/STXR exclusive pairs on ARM64.

Floating-Point & Multi-Return

f32 and f64 types with full arithmetic, comparisons, conversions, and a math library (sin, cos, exp, log, pow, sqrt, fmt_f64). f16 for storage. Hardware sqrt, software trig/exp/log. Multi-return with return (a, b) and 2-tuple destructuring (u64 q, u64 r) = divmod(17, 5). Inline asm I/O constraints: asm { "rdtsc" } out(rax -> lo, rdx -> hi).

Framebuffer & UI

Stdlib modules for bare-metal graphics: std/fb.kr for framebuffer pixel, line, and rectangle drawing; std/font.kr for bitmap font rendering; std/widget.kr for panels, labels, buttons, progress bars, and text fields.

Quickstart

No dependencies required. The compiler is a single static binary. No Rust, no C compiler, no linker needed.

Install
# Linux / macOS (installs krc, kr, and stdlib to ~/.local/)
curl -sSf https://raw.githubusercontent.com/Heniokhos-Systems/KernRift/main/install.sh | sh

# Debian / Ubuntu (signed apt repo — amd64 + arm64)
curl -fsSL https://apt.kernrift.org/kernrift-archive-keyring.gpg | sudo tee /usr/share/keyrings/kernrift-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/kernrift-archive-keyring.gpg] https://apt.kernrift.org/ ./" | sudo tee /etc/apt/sources.list.d/kernrift.list
sudo apt update && sudo apt install kernrift

# If you previously used the install script above, its copies in ~/.local/bin will
# shadow the packaged ones — apt install succeeds but krc --version still reports the
# older version. Run `which krc` and `which kr`: both should print /usr/bin/... If they
# point at ~/.local/bin instead, remove ~/.local/bin/krc, ~/.local/bin/kr, and
# ~/.local/share/kernrift/ so the package's binaries and its /usr/share/kernrift/std win.

# Windows PowerShell (installs krc.exe, kr.exe, and stdlib to %LOCALAPPDATA%\KernRift\)
irm https://raw.githubusercontent.com/Heniokhos-Systems/KernRift/main/install.ps1 | iex

# Homebrew (macOS / Linux)
brew install heniokhos-systems/kernrift/kernrift

# Scoop (Windows)
scoop bucket add kernrift https://github.com/Heniokhos-Systems/KernRift
scoop install kernrift

# Winget (Windows)
winget install Pantelis23.KernRift

# AUR (Arch Linux)
yay -S kernrift

# Or download directly (x86_64 / ARM64)
curl -L -o krc https://github.com/Heniokhos-Systems/KernRift/releases/latest/download/krc-linux-x86_64
curl -L -o kr  https://github.com/Heniokhos-Systems/KernRift/releases/latest/download/kr-linux-x86_64
chmod +x krc kr && sudo mv krc kr /usr/local/bin/
fibonacci.kr — Recursive Functions
fn fib(uint64 n) -> uint64 {
    if n <= 1 { return n }
    return fib(n - 1) + fib(n - 2)
}

struct Point {
    uint64 x
    uint64 y
}

static uint64 counter = 0

fn main() {
    Point p
    p.x = fib(10)     // 55
    p.y = 42
    uint64 msg = "KernRift!\n"
    write(1, msg, 10)
    exit(p.x + p.y)   // 97
}
memory.kr — Unsafe Pointer Operations
// Direct memory access for kernel development
fn main() {
    uint64 buf = alloc(4096)

    // Write a uint32 to memory
    unsafe { *(buf as uint32) = 0xDEADBEEF }

    // Read it back
    uint32 val = 0
    unsafe { *(buf as uint32) -> val }

    // Array operations
    uint8[256] table
    uint64 i = 0
    while i < 256 {
        table[i] = i
        i += 1
    }
    exit(table[42])  // 42
}
kernel.kr — Inline Assembly & Kernel Features
// Naked ISR entry — no compiler-generated prologue
@naked fn isr_timer() {
    asm { "cli"; "nop"; "sti"; "iretq" }
}

// Hardware register manipulation with bitfields
fn enable_paging(uint64 cr0_val) -> uint64 {
    uint64 pg = bit_set(cr0_val, 31)   // set PG bit
    uint64 pe = bit_set(pg, 0)          // set PE bit
    return pe
}

// Signed comparisons for kernel math
fn clamp_signed(uint64 val, uint64 lo, uint64 hi) -> uint64 {
    if signed_lt(val, lo) { return lo }
    if signed_gt(val, hi) { return hi }
    return val
}
Compile & Run
# Compile to fat binary (8 platform slices, BCJ+LZ-Rift-compressed)
$ krc program.kr -o program.krbo

# Run on any platform
$ kr program.krbo

# Or compile for a single architecture and run directly
$ krc --arch=x86_64 program.kr -o program
$ ./program

# Safety analysis
$ krc check module.kr

# Living compiler — patterns + fitness score
$ krc lc program.kr
=== KernRift Living Compiler Report ===
    stable semantic core + adaptive surface layer
Telemetry
  Functions:   12
  Calls:       45
  Unsafe ops:  3
  Patterns:    2
Fitness: 85/100

# The compiler compiles itself
$ krc --arch=x86_64 krc-source.kr -o krc

Bug Reports & Discussions