Flash tutorial · 1 / 12
1. Introduction
Flash is a small, statically typed systems programming language designed specifically for bare-metal and kernel development.
The frontend and pipeline of Flash are designed to replace C and Zig for low-level tasks. The compiler is self-hosted — flashc is written in Flash itself — with the ultimate goal of powering FlashOS, an experimental AArch64 operating system kernel.
The Tier-0 Philosophy
In its current stage, the Flash compiler (flashc) utilizes a Tier-0 strategy:
Rather than compiling directly to machine instructions (like ARM or x86 assembly) or LLVM IR, Flash transpiles directly into human-readable, diffable Zig source code.
[ Flash Source (.flash) ]
│
▼ (compiler frontend: lex, parse, sema)
[ AST & Names Resolved ]
│
▼ (compiler backend: lower)
[ Zig Source (.zig) ]
│
▼ (downstream Zig toolchain)
[ Target Executable / ELF ]
Why Emit Zig?
- Incremental Porting: FlashOS has a codebase of ~26,000 lines of Zig. Emitting Zig modules allows Flash code and existing Zig code to coexist side-by-side. We can rewrite the OS module-by-module.
- Type Checking: Flash leverages the downstream Zig compiler for type safety and optimization checks.
- Auditable Output: The code generated by the compiler is clean and easy to read.
Hello, World! in Flash
Here is a minimal Flash program showing the basic syntax. It imports the systems-level C library helper flibc, writes a string to file descriptor 1 (stdout), and exits.
// hello.flash - the smallest Flash program: write a line, then exit.
use flibc
link "flibc_start"
link "flibc_mem"
export fn main(_ usize, _ argv) noreturn {
msg := "Hello from Flash!\n"
_ = flibc.sys.write_fd(1, msg.ptr, msg.len)
flibc.exit()
}
[!NOTE] All code comments in Flash start with
//and are treated as trivia by the compiler (they are omitted from the lowered Zig code). Flash enforces braces{}for function and control blocks. The two_parameters onmainstand in for its argument count and vector — this program ignores them, and because Flash rejects an unused parameter or value,_is how you intentionally discard one.
Key Language Goals
- Statically Typed: Types are checked compile-time downstream.
- Semicolon-Free: Clean, modern Go-like grammar layout.
- Explicit Memory Control: Clean pointers, slices, and resource lifecycles.
- Zero Overhead: Lowers directly to optimal systems code.