A small statically-typed systems language that compiles to LLVM IR and then to a native binary. C-like syntax, a modern type system, real SIMD, first-class C interop, and no runtime.
use std
fun main() >> void {
println("Hello, World!");
}
ZLang is small enough to read end to end and ships with the things you actually want for real work: a flexible type system, direct C interop, first-class SIMD, guard clauses, expression blocks, and a real error flow. LISP in the middle of your function as an inline block, because the compiler is built to be extended.
zig build system-install
zlang examples/hello_world.zl
zlang examples/hello_world.zl -o hello -optimizezlang run <file.zl> builds, executes, and cleans up in one step; the
exit code is propagated to the shell. For exploration, zlang zli
drops you into an interactive REPL with :load / :files / :quit.
Zig 0.16, Flex, Bison 3.x, and LLVM/Clang 22 are required. Currently targets
linux-x86_64. Check your build with zlang -version.
A short tour of the language, from examples/:
fun factorial(n: i32) >> i32 {
if n <= 1 { return 1; }
return n * factorial(n - 1);
}
fun main() >> i32 {
printf("5! = %d\n", factorial(5));
return 0;
}
Pointers, arrays, SIMD, expression blocks, and guard clauses — same shape as C, fewer footguns:
fun divide(a: i32, b: i32) when (b != 0) >> i32 {
return a / b;
}
i32 score = <i32> {
i32 base = 40;
i32 bonus = 2;
base + bonus
};
simd<f32, 4> v = {1.0, 2.0, 3.0, 4.0};
C interop is just a @ prefix or wrap declarations:
wrap printf(format: ptr<u8>) >> i32;
fun @malloc(size: u64) >> ptr<void>;
fun main() >> i32 {
ptr<i32> buf = @malloc(100) as ptr<i32>;
*buf = 42;
printf("%d\n", *buf);
return 0;
}
ZLang doesn't have exceptions or Result types. It has two explicit,
resumable signal channels declared at the language level: a callee either
notifies the caller that something happened, or solicits the
caller's help to keep going. The caller can ignore them, handle them, or
mutate the callee's local state to fix the problem in place.
Errors are named up front:
error FileNotFound = 1;
error FileLocked = _; ?? _ assigns an automatic unique code
A function sends a signal to report an event. The caller catches it with
on at the call site:
fun open_file(path: ptr<u8>) >> i32 {
if path == null { send FileNotFound; }
return 0;
}
fun main() >> i32 {
open_file(null)
on FileNotFound { println("not found"); }
on _ { println("something else"); };
return 0;
}
solicit is the unusual one. The callee pauses mid-expression, the caller
gets to inspect and rewrite the callee's locals, and execution continues
inside the callee — no propagation, no rethrow, no return-trip:
error NeedSeed = _;
fun next_value() >> i32 {
i32 seed = 0;
solicit NeedSeed; ?? caller decides what seed should be
return seed + 41;
}
fun main() >> i32 {
i32 out = next_value() on solicit NeedSeed {
seed = 1; ?? we reach into next_value's local `seed`
};
printf("%d\n", out); ?? 42
return 0;
}
solicit is its own channel: on doesn't catch it, and on solicit
doesn't catch send. Handlers attach at the call expression and match by
name, by code, or by _. See the full reference in
DOCUMENTATION.md.
The compiler is modular. Brainfuck, Lisp, threading, file-type handlers —
all live as separate .zlx packages. Install, list, and load them through
the compiler itself:
zlang module install ./brainfuck.zlx
zlang module list
zlang module load-order ?? topological order of installed plugins
zlang module dev ./myext ?? auto-reload on change (Linux)
zlang module helpOnce installed, plugin syntax is just a normal block in your source:
fun main() >> i32 {
brainfuck {
++++++++[>++++++++<-]>+.
}
return 0;
}
The work's in progress, see EXTENSIONS_ROADMAP.md.
Arch Linux (AUR):
# AppImage — no build needed, comes with bundled stdlib
yay -S zlang-bin
# Build from source, tracks latest git
yay -S zlang-gitzlang-bin— pre-built AppImage, installs as/usr/bin/zlangzlang-git— builds from source, requires LLVM + Zig 0.16
Build from source:
See INSTALL.md for full instructions, dependency lists per distro, and verified platforms.
git clone https://github.com/zlangdevs/zlang
cd zlang
zig build system-install.zl source → Flex lexer → Bison GLR parser → AST (Zig)
→ zlx preprocessor (extension blocks)
→ Zig LLVM IR generator → clang/llvm-toolchain → native binary
Frontend is Flex + Bison GLR. Backend is a custom Zig generator on top of
the LLVM C API. Extensions are .zlx packages with a stable C ABI v6 and
host-side dlopen with explicit handshake. Core language keywords are
reserved by the host; in v6, attempting to register_syntax_block a
core keyword name returns ZLANG_REGISTER_RESERVED — use
register_keyword_block to override on purpose.
The full language reference, stdlib, error flow, and codegen internals live in DOCUMENTATION.md.
For a hands-on walkthrough of the compiler's feature surface as it actually ships, see examples/README.md. It groups the 29 example programs and 67 integration tests by topic (getting started, stdlib, C interop, modules, the CHIP-8 emulator, plugins) and points at the test files that double as small language-references.
ZLang projects under the zlangdevs org:
- zltris — Tetris on raylib with a network protocol; the largest zlang codebase so far.
- brainfuck-zlx —
brainfuck { ... }blocks and standalone.b/.bffiles. - zlsip —
lisp { ... }blocks with bidirectional zlang/lisp calls and template macros. - raylib-zl — Raylib bindings.
- ncurses-zl — ncurses wrapper.
- zlib — standard library modules.
- zed-zlang — Zed syntax extension.
- zlang-vscode — VS Code syntax highlighting (WIP).
- zl-cloc — cloc fork that counts zlang code.
Active development. Open areas: stdlib coverage, more optimization passes,
error message polish, IDE plugins, documentation. Extensions are especially
welcome — write a .zlx against the v1 C ABI in include/ and ship it.
See CONTRIBUTING.md for build setup, test conventions, and PR guidelines.
GNU GPL v3.0. See LICENSE.
Empire starts here 😈
Made with ⚡ by the ZLang team