ZEPHYR v0.2 — zc terminal
man zephyr
======================================================
 ZEPHYR(1) — the manual · v0.2
======================================================
a small, statically-typed, memory-safe language that
compiles to native x86-64 — as readable as a scripting
language, as fast as C, with a compiler written in
itself. sections below: overview, getting started,
language, stdlib, toolchain.
cat 00-overview.txt

Overview

point.zeph
struct Point { x: float, y: float }

fn dist(a: Point, b: Point) -> float {
    let dx = a.x - b.x
    let dy = a.y - b.y
    return sqrt(dx * dx + dy * dy)
}

let b = Point{x: 3.0, y: 4.0}
print("distance is {dist(a, b)}")   // 5
print(b.dist(a))                    // UFCS

Performance

Best-of-7, Windows x86-64, Zen5, same algorithm with a verified checksum:

WorkloadZephyrC −O2Rust −OResult
integer SIMD (matmul)427270wins both
rasterization (cube)81011wins both
bignum (pi)668491wins both
sorting139276432× faster than C
recursion (fib)211221ties Rust
float compute (mandel)1098890within 1.2×
cat 01-getting-started.txt

Getting started

Requirements: Windows x86-64 and zc.exe — a single self-contained file with the runtime and standard library embedded. No separate runtime, no linker to configure, no C toolchain.

hello.zeph
fn main() {
    print("Hello from Zephyr!")
}
$ .\zc.exe --rt hello.zeph hello.exe
$ .\hello.exe
Hello from Zephyr!

hello.exe is a standalone Windows executable that imports only kernel32.dll. --rt links Zephyr's own runtime; end the output path in .s to emit Intel-syntax assembly instead.

Multi-file

// math.zeph
fn square(n: int) -> int { return n * n }

// main.zeph
import "math.zeph"
fn main() { print(square(9)) }   // 81

import resolves relative to the importing file, then the compiler's directory. Each file is included once — diamond imports are fine.

cat 02-language.txt

The language

let is immutable, var is mutable; locals infer their type and every variable is initialized. int widens to float implicitly; every other conversion is explicit with as.

TypeNotes
int64-bit signed integer
float64-bit floating point
booltrue / false
strimmutable string, UTF-8 bytes

Operators: arithmetic + - * / %, comparison == != < > <= >=, short-circuiting and or not, bitwise & | ^ << >>. Control flow is if / else if / else, while with break/continue, and for x in xs / for i in 0..n (half-open).

Structs, impl & UFCS

impl Point {
    fn new(x: float, y: float) -> Point {   // constructor
        return Point{x: x, y: y}
    }
    fn len(self) -> float {                  // method
        return sqrt(self.x*self.x + self.y*self.y)
    }
}
let p = Point.new(3.0, 4.0)
print(p.len())      // 5
print(p.dist(a))    // UFCS: same as dist(p, a)

Interfaces & enums

interface Shape {
    fn area(self) -> float
    fn name(self) -> str
}
fn describe(s: Shape) { print("{s.name()}: {s.area()}") }

enum Color { Red, Green, Blue }
print(Color.Green)   // Green — prints its member name

Collections & optionals

fn find(xs: [int], target: int) -> int? {
    for v in xs { if v == target { return v } }
    return none
}
let v = find(xs, 9).or(0)    // default if absent
An empty list literal [] cannot infer its element type — annotate the binding: var xs: [int] = [].

Generics & closures

fn contains[T](xs: [T], x: T) -> bool {
    for v in xs { if v == x { return true } }
    return false
}
print(contains([1, 2, 3], 2))      // T = int

fn make_adder(n: int) -> fn(int) -> int {
    return fn(x: int) -> int { return x + n }
}
print(make_adder(5)(10))              // 15
cat 03-stdlib.txt

Standard library

Functionality splits between a small set of compiler built-ins and a standard library written in Zephyr (std/) — ordinary generic code, not special-cased.

Built-inPurpose
print(x)Print a value (any type) + newline
panic(msg)Abort with a message
assert(cond, msg)Abort if cond is false
args()Command-line arguments as [str]
read_file / write_fileFile I/O

Math

sqrtabsminmaxpowbitsfrombitschr

String methods

.len().sub(a,b).split(sep).join().contains(s).index_of(s).starts_with(s).upper().lower().trim().replace(a,b).repeat(n)

List · map · optional

.push(v).pop().sort()xs[i].has(k).get(k).remove(k).keys().values().or(default)
std/list.zeph
import "std/list.zeph"
print(xs.contains(2))   // generic Zephyr, UFCS
Low-level built-ins (load64, store64, addr, win(...) for Win64 FFI) exist for the runtime and FFI — most code never touches them.
cat 04-toolchain.txt

Compiler & toolchain

zc.exe — written in Zephyr — is one self-contained binary: lexer, recursive-descent parser, type checker, optimizer, x86-64 code generator, its own assembler, and its own PE linker. No gcc, no ld, no external assembler.

lexer -> parser -> type checker -> inliner
  -> optimizer passes -> x86-64 codegen
  -> peephole -> assembler -> PE linker
  -> app.exe   // imports: kernel32.dll

The runtime is itself written in Zephyr (runtime.zeph): allocation, strings, collections, formatting, and a conservative mark-sweep GC — a contiguous reserved heap with an object-start bitmap for O(1) pointer identification, size-segregated free lists, roots scanned from the machine stack and globals, and a live-proportional collection trigger.

Self-hosting

The production compiler selfhost/zc.zeph compiles itself; a one-time C seed produced the first binary, and gcc has been out of the loop ever since. Any change to codegen is promoted through a three-stage bootstrap to a byte-identical fixpoint.

$ .\selfbuild.ps1   # recompiles zc.zeph; checks the fixpoint

The optimizer