:sovereign — The Citadel
:sovereign — The Citadel
Section titled “:sovereign — The Citadel”“No abstraction left behind.”
:sovereign is where Janus becomes a systems language in the truest sense. Everything from every profile — plus raw pointers, full comptime, complete effect system, and unsafe blocks. This is where operating systems, drivers, and bare-metal software live. If you need absolute control, welcome home.
What :sovereign Gives You
Section titled “What :sovereign Gives You”Raw Pointers
Section titled “Raw Pointers”func write32(addr: *volatile u32, value: u32) void do unsafe { addr.write(value) }end*T— Direct memory address*volatile— Memory-mapped I/O- Pointer arithmetic — When you need it
- Zero-cost abstraction — Same performance as C
Full Comptime
Section titled “Full Comptime”const FIB_TABLE = comptime do var table: [100]u64 = undefined table[0] = 0 table[1] = 1 for i in 2..100 do table[i] = table[i-1] + table[i-2] end return tableend- Compile-time execution — Any Janus function
- Type-level programming — Types as values
- Zero runtime cost — Computed once at compile time
Complete Effect System
Section titled “Complete Effect System”effect IoError { type: String, code: i32,}
handler handle_io_error(e: IoError) -> i32 do print("IO error: ${e.type}") return -1end- First-class effects — Effects are values
- Effect handlers — Custom control flow
- Inlining — No overhead vs. manual code
Unsafe Blocks
Section titled “Unsafe Blocks”func memcpy(dest: *u8, src: *u8, n: usize) void do unsafe { for i in 0..n do dest.add(i).write(src.add(i).read()) end }end- When you need to do things the compiler can’t verify
- Explicit — Everyone sees it’s unsafe
- Documented — Unsafe code gets reviewed
Capabilities
Section titled “Capabilities”func write_to_device(addr: *volatile u32) void requires CapDeviceWritedo unsafe { addr.write(0xDEADBEEF) }end- Fine-grained system capability control
- Compile-time verification
- No sudo needed — capabilities are declared, not granted
What :sovereign Includes
Section titled “What :sovereign Includes”Everything from every other profile:
:core— Types, control flow, functions:script— Convenience features (with explicit profile declaration):service— Error handling, async/await, channels:cluster— Actors, grains, supervision:compute— Tensors, memory spaces, device targeting
When to Use :sovereign
Section titled “When to Use :sovereign”Perfect for:
- Operating system kernels
- Device drivers
- Bootloaders and firmware
- Real-time systems with hard latency requirements
- Custom memory allocators
- VM hypervisors
- Bare-metal embedded (no OS)
The rule: If you need to do something the language normally prevents, :sovereign lets you — with explicit acknowledgment that you’re doing something dangerous.
Code Examples
Section titled “Code Examples”A Simple OS Kernel
Section titled “A Simple OS Kernel”# Sovereign code - no runtime, no stdlib
struct GDTEntry { limit_low: u16, base_low: u16, base_mid: u8, access: u8, flags: u8, base_high: u8,}
func setup_gdt() void do let gdt: *mut GDTEntry = 0x80000 as *mut GDTEntry
# Null descriptor gdt.write(GDTEntry.zero())
# Code segment (ring 0) gdt.offset(1).write(GDTEntry{ limit_low: 0xFFFF, base_low: 0x0000, base_mid: 0x00, access: 0x9A, # Present, ring 0, executable flags: 0xCF, # 32-bit, 4KB granularity base_high: 0x00, })
# Data segment (ring 0) gdt.offset(2).write(GDTEntry{ limit_low: 0xFFFF, base_low: 0x0000, base_mid: 0x00, access: 0x92, # Present, ring 0, writable flags: 0xCF, base_high: 0x00, })
# Load GDTR unsafe { lgdt(gdt_descriptor) }endCustom Memory Allocator
Section titled “Custom Memory Allocator”struct BlockHeader { size: usize, is_free: bool, next: *BlockHeader,}
struct BumpAllocator { start: *u8, current: *u8, end: *u8,}
func BumpAllocator.new(base: *u8, size: usize) BumpAllocator do return BumpAllocator{ start: base, current: base, end: base.add(size), }end
func (self: *BumpAllocator) alloc(size: usize) ?*u8 do let aligned = align_up(self.current, 8) let new_current = aligned.add(size)
if new_current > self.end do return .none end
self.current = new_current return alignedendDevice Driver (Memory-Mapped I/O)
Section titled “Device Driver (Memory-Mapped I/O)”const UART_BASE: *volatile u32 = 0x10000000 as *volatile u32const UART_DATA: volatile_offset = 0x00const UART_STATUS: volatile_offset = 0x04const UART_CTRL: volatile_offset = 0x08
func uart_init() void do unsafe do # Disable interrupts UART_BASE.offset(UART_CTRL).write(0)
# Set baud rate (assuming 1MHz clock) UART_BASE.offset(0x09).write(1) # Divisor latch UART_BASE.offset(0x08).write(0) # LSB UART_BASE.offset(0x09).write(0) # MSB
# 8N1, enable FIFO UART_BASE.offset(UART_CTRL).write(0x03) endend
func uart_putc(c: u8) void do unsafe do while UART_BASE.offset(UART_STATUS).read() & 0x20 == 0 do # Wait for TX buffer empty end UART_BASE.offset(UART_DATA).write(c) endendWhy :sovereign Wins
Section titled “Why :sovereign Wins”vs. C:
- Types — Catch bugs at compile time
- Comptime — Generate code at compile time
- No undefined behavior — Well-defined semantics
- Interop — Call into Zig stdlib when needed
vs. Rust:
- Simpler — No borrow checker friction
- Effects — More flexible than Result/Option
- Same performance — Zero-cost abstractions
vs. Zig:
- Types — More expressive than Zig’s
- Profile system — Clear migration path from script to sovereign
- Effect system — Built-in, not a library
A Note on Safety
Section titled “A Note on Safety”:sovereign is not “dangerous Janus.” It’s honest Janus. When you write unsafe {}, the compiler knows you’re doing something that could go wrong. It’s all explicit. There’s no hidden state, no surprising behavior, no “trust me” code.
You have the power. Use it wisely.
Next Steps
Section titled “Next Steps”- Profile Overview — See all six profiles
- Reference: SBI — Supervisor Binary Interface
- Architecture Docs — Deep dive into the effect system
Total control. Zero compromise.