TL;DR
After building a real-time OS and hitting the limitations of C, we created Tempo - a systems programming language with memory safety, deterministic execution, and zero overhead. It's not a toy - we're using it to build AtomicOS.
The Problem
Every few months, someone announces a "C killer" that turns out to be either:
Too high-level for real systems programming
Too complex (looking at you, Rust)
Missing critical features like inline assembly
Just... not actually replacing C
We were building AtomicOS, a deterministic real-time security OS, and kept running into C's fundamental issues:
Memory unsafety is baked into the language
Undefined behavior everywhere
No way to guarantee execution time
The preprocessor is a footgun factory
Enter Tempo v1.0.0
Instead of complaining, we built the language we needed. Here's what makes Tempo different:
1. Structs That Actually Work for Systems Programming
struct DMADescriptor @packed @align(16) {
buffer: raw_ptr<int8>,
size: int32,
flags: int32,
next: ptr<DMADescriptor>
}
Real memory layout control. No hidden padding. No surprises.
2. A Pointer System That Makes Sense
// Safe by default - bounds checked at compile time
function process_buffer(data: ptr<int8, 256>) {
for i in 0..256 {
data[i] = transform(data[i]); // Can't overflow!
}
}
// Explicit unsafe when you need it
function mmio_read(addr: int32) -> int32 {
let p: raw_ptr<int32> = addr as raw_ptr<int32>;
return *p;
}
3. Inline Assembly as a First-Class Feature
`@interrupt
function timer_handler() {
asm volatile("push eax");
asm volatile("push ebx");
tick_count = tick_count + 1;
// Send EOI to PIC
outb(0x20, 0x20);
asm volatile("pop ebx");
asm volatile("pop eax");
asm volatile("iret");
}`
No more writing separate assembly files and hoping your calling conventions match!
4. Deterministic by Design
Every loop must be bounded. Every operation has known timing:
function process_packets(packets: ptr<Packet, 64>) @wcet(6400) {
for i in 0..64 @wcet(100) {
if packets[i].valid {
handle_packet(&packets[i]);
}
}
}
The compiler proves this function completes in 6400 cycles or less.
Real-World Usage
This isn't theoretical. We're building an entire OS with Tempo:
Boot loader ✅
Interrupt handlers ✅
Memory management ✅
Process scheduler ✅
Device drivers ✅
Network stack 🚧
Check out our kernel written entirely in Tempo: kernel_in_tempo.tempo
Performance
Tempo compiles to the same assembly you'd write by hand:
function add(a: int32, b: int32) -> int32 {
return a + b;
}
Compiles to:
add:
mov eax, [esp+4]
add eax, [esp+8]
ret
No runtime. No hidden allocations. No surprises.
Getting Started
git clone https://github.com/ipenas-cl/AtomicOS.git
cd AtomicOS
make build/tempo_compiler
# Write your first Tempo program
echo 'function main() -> int32 { return 42; }' > hello.tempo
./build/tempo_compiler hello.tempo hello.s
The Future
Tempo v1.0.0 is just the beginning. We're working on:
Generic types (without the complexity)
Async/await for interrupt-driven I/O
Formal verification integration
ARM and RISC-V backends
Join Us!
We need contributors! Whether you're interested in:
Compiler development
Language design
Systems programming
Documentation
Building cool stuff with Tempo
There's a place for you in the project.
🌐 Website: https://ipenas-cl.github.io/AtomicOS/tempo/
💻 GitHub: https://github.com/ipenas-cl/AtomicOS
💬 Discussions: https://github.com/ipenas-cl/AtomicOS/discussions
Let's build the future of systems programming together!
Top comments (0)