Zlang
No description available
Install / Use
/learn @zlangdevs/ZlangREADME
🚀 ZLang
A fast, clean systems programming language that compiles to LLVM IR
ZLang combines the simplicity of C with modern features like SIMD, function templates, and embedded Brainfuck support. Write efficient, low-level code without the ceremony.
fun main() >> i32 {
@printf("Empire starts here 😈\n");
return 0;
}
📖 Full Documentation | 🔧 Examples
✨ Features
- 🎯 Simple & Clean Syntax - Familiar C-like syntax with modern improvements
- ⚡ SIMD Built-in - First-class SIMD vector support for high-performance computing
- 🔧 Direct C Interop - Call C functions with
@prefix, seamless libc integration - 🏗️ Modern Type System - Structs with default values, enums, function templates, and overloads
- 🔒 Const Pointers - Compile-time safety with read-only pointer guarantees
- 🔄 Smart Loops - Infinite, conditional, and C-style
forloops - 🛡️ Guard Clauses - Function-level preconditions with
when (...) - 🧩 Expression Blocks -
<type> { ... }blocks that return values - 🚨 Error Flow v2 -
error,send,solicit, and call-siteonhandlers - 🔢 Numeric Error Matching - Handle by code with
on 1 { ... }/on solicit 1 { ... } - 🧠 Brainfuck Integration - Embed Brainfuck code directly or compile pure .bf files!
- 🎨 Type Inference - Auto-cast with
as _for cleaner code - 📦 Zero Runtime - Compiles directly to LLVM IR, no runtime overhead
🚦 Quick Start
Installation
# Build the compiler
zig build
# Install compiler + stdlib to system paths
zig build install
# Remove system install
zig build uninstall
# Compile a ZLang program
./zig-out/bin/zlang examples/hello_world.zl
# Compile with optimizations and specify output name, keep LLVM IR
./zig-out/bin/zlang myprogram.zl -o myprogram -optimize -keepll
# Compile pure Brainfuck programs
./zig-out/bin/zlang -b mandelbrot.bf -o mandelbrot
./zig-out/bin/zlang -b32 program.bf -o output # 32-bit cells
# Generate wrappers from C headers
./zig-out/bin/zlang wrap mylib.h -o mylib.zl
./zig-out/bin/zlang wrap-clang mylib.h -o mylib_abi.zl
Hello World
fun main() >> i32 {
@printf("Hello, World!\n");
return 0;
}
Factorial Function
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;
}
📖 Language Guide
Variables & Types
i32 count = 42; ?? Signed integers: i8, i16, i32, i64
u64 big_num = 1000000; ?? Unsigned: u8, u16, u32, u64
f32 temperature = 98.6; ?? Floats: f16, f32, f64
bool is_active = true; ?? Booleans
ptr<i32> my_ptr = &count; ?? Mutable pointer to mutable data
ptr<const i32> ro_ptr = &count; ?? Pointer to const data (value can't change)
const ptr<i32> fixed = &count; ?? Const pointer (pointer can't be reassigned)
arr<i32, 100> numbers; ?? Fixed-size arrays
const i32 MAX = 100; ?? Constant variables
Note: Comments use ?? instead of //
Control Flow
If Statements
if temperature > 100.0 {
@printf("Too hot!\n");
} else if temperature < 0.0 {
@printf("Freezing!\n");
} else {
@printf("Just right\n");
}
Loops - The ZLang Way
?? Infinite loop
for {
@printf("Forever\n");
break;
}
?? Simple variable (no parentheses!)
i32 countdown = 5;
for countdown {
@printf("%d...\n", countdown);
countdown--;
}
?? Complex expressions (parentheses required)
for (i < 10 && i != 5) {
i++;
}
?? C-style loops
for i32 i = 0; i < 10; i++ {
@printf("i = %d\n", i);
}
Guard Clauses
fun divide(a: i32, b: i32) when (b != 0) >> i32 {
return a / b;
}
Expression Blocks
i32 score = <i32> {
i32 base = 40;
i32 bonus = 2;
base + bonus
};
Error Flow (send, solicit, on)
error FileNotFound = 1;
error PermissionDenied = 1;
error FileLocked = _;
fun open_file(path: ptr<u8>, ro: bool) >> i32 {
if path == "missing" {
send FileNotFound;
return -1;
}
if path == "protected" && !ro {
solicit PermissionDenied;
}
if path == "locked" {
send FileLocked;
return 0;
}
return 1;
}
fun main() >> i32 {
i32 res = open_file("protected", false)
on 1 { @printf("shared code=1 handler\n"); }
on solicit PermissionDenied { ro = true; }
on _ {}
on solicit _ {};
@printf("Result: %d\n", res);
return 0;
}
Handler forms:
on ErrorName { ... }on 1 { ... }on _ { ... }on solicit ErrorName { ... }on solicit 1 { ... }on solicit _ { ... }
Structs
struct Point {
x i32,
y i32,
}
struct Person {
name arr<u8, 50> = "Anonymous",
age i32 = 0,
active bool = true
}
fun main() >> i32 {
Point p = {10, 20};
Person john = {.name = "John", .age = 30};
@printf("Point: (%d, %d)\n", p.x, p.y);
@printf("Person: %s, age %d\n", john.name, john.age);
return 0;
}
Enums
enum Status {
IDLE,
RUNNING = 100,
COMPLETED,
FAILED = 200
}
fun main() >> i32 {
i32 current = Status.RUNNING;
?? Also supports C-style direct access
if current == RUNNING {
@printf("Program is running\n");
}
return 0;
}
SIMD Vectors
fun main() >> i32 {
?? Create SIMD vectors
simd<f32, 4> v1 = {1.0, 2.0, 3.0, 4.0};
simd<f32, 4> v2 = {5.0, 6.0, 7.0, 8.0};
?? Vectorized operations
simd<f32, 4> sum = v1 + v2;
simd<f32, 4> product = v1 * v2;
?? Access elements
@printf("sum[0] = %.1f\n", sum[0]);
?? Modify elements
v1[2] = 100.0;
return 0;
}
Type Casting
i32 x = 42;
f32 y = x as f32; ?? Explicit cast
f64 z = x as _; ?? Auto-infer target type
?? Pointer casting
ptr<void> raw = &x as ptr<void>;
ptr<i32> typed = raw as ptr<i32>;
Pointers & References
i32 value = 100;
ptr<i32> p = &value; ?? Take address
i32 deref = *p; ?? Dereference
*p = 200; ?? Modify through pointer
?? Pointer to const - cannot modify value, can reassign pointer
ptr<const i32> readonly = &value;
i32 read = *readonly; ?? ✅ Reading is OK
*readonly = 50; ?? ❌ Compile error: Cannot modify through pointer to const
readonly = &other_value; ?? ✅ Can reassign pointer
?? Const pointer - cannot reassign pointer, can modify value
const ptr<i32> fixed = &value;
*fixed = 50; ?? ✅ Can modify value
fixed = &other_value; ?? ❌ Compile error: Cannot reassign const variable
?? Pointer arithmetic
p = p + 1;
?? Pass by reference
fun increment(val: ptr<i32>) >> void {
*val = *val + 1;
}
?? Const parameters prevent modification
fun read_only(val: ptr<const i32>) >> i32 {
return *val; ?? OK to read, cannot modify
}
C Interop
Call any C function with @ prefix:
?? External C function declarations
fun @printf(format: ptr<u8>) >> i32;
fun @malloc(size: u64) >> ptr<void>;
fun @free(ptr: ptr<void>) >> void;
fun main() >> i32 {
ptr<i32> buffer = @malloc(100) as ptr<i32>;
*buffer = 42;
@printf("Value: %d\n", *buffer);
@free(buffer as ptr<void>);
return 0;
}
Use wrap for automatic C ABI compatibility:
wrap @some_c_function(x: i32, y: f32) >> i32;
📦 Imports and Standard Library
ZLang supports importing other modules using the use directive.
- Modules are declared in source files:
module net.http; - Imports are by module name:
use net.http - Prefix imports include submodules:
use netimportsnetandnet.* - Standard library modules:
use std.<module>loads modules from the standard library.
Example:
module app.main;
use net.http;
fun main() >> i32 {
return 0;
}
module net.http;
fun get(url: ptr<u8>) >> i32 {
return 200;
}
Standard Library Resolution
When you import std.<module>, ZLang searches for <module>.zl in:
- The directory specified by the
ZSTDPATHenvironment variable. - If
ZSTDPATHis not set, thestdlib/directory located next to the compiler binary.
Example layout:
zlang # compiler binary
stdlib/ # default stdlib directory if ZSTDPATH is not set
random.zl
You can explicitly set ZSTDPATH:
export ZSTDPATH=/path/to/zlang/stdlib
If a standard module cannot be found, the compiler prints a clear error indicating it searched ZSTDPATH or the default stdlib/ directory.
Using std.random
The std.random module wraps libc random functions and provides helpers.
use std.random
fun main() >> i32 {
srand(42);
i32 r = rand();
@printf("rand(): %d\n", r);
i32 dice = randRange(1, 6);
@printf("dice: %d\n", dice);
return 0;
}
Provided symbols:
- srand(seed: u32) >> void
- rand() >> i32
- randRange(min: i32, max: i32) >> i32
- time(t: ptr<i64>) >> i64
Using std.math
The std.math module wraps common mathematical functions from libm.
use std.math
fun main() >> i32 {
f64 x = 16.0;
f64 root = sqrt(x);
@printf("sqrt(%.1f) = %.2f\n", x, root);
f64 angle = toRadians(90.0);
f64 sine = sin(angle);
@printf("sin(90°) = %.6f\n", sine);
f64 dist = distance(0.0, 0.0, 3.0, 4.0);
@printf("distance = %.1f\n", dist);
return 0;
}
Provided symbols:
- sqrt(x: f64) >> f64 - Square root
- pow(base: f64, exp: f64) >> f64 - Power function
- sin(x: f64) >> f64, cos(x: f64) >> f64 - Trigonometric functions
- fabs(x: f64) >> f64 - Absolute value for floats
- square(x: f64) >> f64, cube(x: f64) >> f64 - Helper functions
- distance(x1, y1, x2, y2) >> f64 - Euclidean distance
- **toRadians
