v1.0 · Written in Pure C

ZayneScript

A dynamic, interpreted scripting language written in pure C. First-class functions, closures, async/await, BigInt, OOP, and a rich built-in standard library — all in a single executable.

Language Guide Standard Library Quick Start

Dynamic Typing

Variables hold any type at runtime. No annotations required — write expressive code without ceremony.

🔒

First-Class Functions

Functions are values. Pass them around, return them from other functions, and capture variables in closures.

🔄

Async / Await

Declare async functions and use await to suspend execution. Includes Promise chaining with .then() and .error().

🔢

BigInt Support

Arbitrary-precision integers using the n suffix — 100n + 2n. No overflow surprises with large numbers.

🏗️

Object-Oriented

Class-based inheritance, constructors, static methods/properties, and this binding.

📦

Module System

Named and wildcard imports, core: built-ins, lib: user libraries, and relative path imports.

🗃️

Rich Data Structures

Dynamic arrays with methods (push, pop, each, keep), and flexible key-value objects with spread syntax.

🎛️

Expressive Control Flow

if/for/while/do-while, switch expressions, try/catch, and ternary forms.

📚

Standard Library

Built-in modules for I/O, math, OS utilities, arrays, dates, and promises. Import only what you need.

🌐

HTTP Server

Express.js-style HTTP server via core:mongoose. Register GET/POST/… routes, attach middleware, and serve JSON APIs — all from ZayneScript.

Quick Start

Build — requires GCC. Choose the method that matches your platform.

Makefile — Linux / macOS (recommended, uses clang):

# Debug build with AddressSanitizer (default)
make

# Super-optimised release build (clang + LTO)
make release

# Build then run immediately
make run

# Install to /usr/local/bin
make install

# Remove the binary
make clean

run.sh — Linux / macOS shell script (uses gcc):

# Debug build + run
./run.sh

# Optimised release build + run
./run.sh --release

# Compile only (no run)
./run.sh --compile

# Format all source files with clang-format
./run.sh --format

# Debug a script with GDB
./run.sh --dbg tests/test_async.zs

run.bat — Windows (MinGW / GCC):

# Debug build + run
.\run.bat

# Optimised release build + run
.\run.bat --release

# Compile only (no run)
.\run.bat --compile

# Debug a script with GDB
.\run.bat --dbg tests\test_async.zs

Manual — any platform with GCC:

gcc -O3 -DNDEBUG -Wno-pointer-sign \
    main.c src/core/*.c src/*.c utf/*.c utf/utf8proc/*.c ./libbf/*.c \
    -o zscript.exe -lm -ldl -lpthread
Write a script — create hello.zs:
import { println } from "core:io";

println("Hello, ZayneScript!");
Run it:
./zscript.exe --run hello.zs

A Taste of ZayneScript

The following snippet demonstrates variables, closures, classes, async/await, and the standard library:

import { println, format } from "core:io";
import { sqrt, pi }        from "core:math";

// ----- Closures -----
fn makeCounter() {
    local count = 0;
    return fn() {
        count += 1;
        return count;
    };
}

var tick = makeCounter();
println(tick(), tick(), tick()); // 1 2 3

// ----- Classes with inheritance -----
class Shape {
    fn area() { return 0; }
}

class Circle (Shape) {
    fn init(r) { this.r = r; }
    fn area()  { return pi * this.r * this.r; }
}

const c = new Circle(5);
println(format("Area: {}", c.area())); // Area: 78.539816...

// ----- Async / Await -----
fn fetchData() async { return "payload"; }

fn main() async {
    const data = await fetchData();
    println("Got:", data); // Got: payload
}

main();

// ----- BigInt -----
println(2n ** 64n); // 18446744073709551616n

Building

Makefile targets

Target Description
make / make debug Debug build with AddressSanitizer & leak detection (clang -g3 -fsanitize=address,leak)
make release Super-optimised build (-O3 -march=native -flto=thin, stripped binary)
make run Debug build then launch the interpreter
make clean Remove zscript.exe
make install Install binary to /usr/local/bin/zscript and libs to /usr/local/lib/zscript/
make uninstall Remove installed binary and library directory
make amalgamate Bundle everything into a single source file via amalgamate.py

run.sh flags (Linux / macOS)

Flag Description
(none) Debug build then run the interpreter
--release Release build then run
--compile Compile only, no run
--format Run clang-format over all src/ files
--dbg <file.zs> Launch gdb with auto run and bt on the given script

run.bat flags (Windows)

Flag Description
(none) Debug build then run the interpreter
--release Release build then run
--compile Compile only, no run
--dbg <file.zs> Launch gdb with auto run and bt on the given script

Usage

Command Description
./zscript.exe --run <file.zs> Execute a script file
./zscript.exe --tests Run all scripts in the tests/ directory
./zscript.exe --help Print help text

Project Structure

Path Contents
src/ Interpreter core: lexer, parser, compiler, bytecode evaluator
src/core/ Standard library modules (io, math, os, array, date, promise)
tests/ Example .zs scripts demonstrating every feature
lib/ User-level library files importable via lib:
utf/ UTF-8 processing helpers (utf8proc)
libbf/ BigInt backend (libbf)
main.c Interpreter entry point