ajhahn.de
← all chapters

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?

  1. 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.
  2. Type Checking: Flash leverages the downstream Zig compiler for type safety and optimization checks.
  3. 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 on main stand 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.