eskiuv0.12.0
Quickstart

Get Eskiu running

Install the compiler, write your first program and run it. A few minutes start to finish, with no toolchain to assemble.

Install

On macOS or Linux, the install script picks the build for your machine and puts it on your PATH:

curl -fsSL https://eskiu-lang.org/install.sh | sh
eskiuc --version
Eskiu 0.12.0 (LLVM ...)

With Homebrew:

brew install eskiu-lang/eskiu/eskiu

Or download a release archive and unpack it anywhere: it holds bin/eskiuc and the standard library in lib/eskiu/stdlib/. On Windows, unzip it and add its bin folder to PATH.

↓ macOS (Apple Silicon) ↓ Linux (x86-64) ↓ Linux (arm64) ↓ Windows (x86-64)

Linking needs a C toolchain on your machine (clang or gcc), the same one Rust and Clang call to produce a binary. macOS has it with the Xcode command-line tools; on Linux, install build-essential (or gcc); on Windows, MinGW from MSYS2. Windows is validated end to end on a native CI runner but is not yet part of the release gate.

Hello, Eskiu

A file of statements runs as a script. Create hello.esk:

import <io>;

println("Hello, Eskiu!");
eskiuc run hello.esk
Hello, Eskiu!

eskiuc run builds a native binary, runs it and cleans up. Larger programs have a main:

import <io>;

int add(int a, int b) {
    return a + b;
}

int main() {
    println("Hello from Eskiu!");
    printf("5 + 3 = %d\n", add(5, 3));
    return 0;
}

To keep the binary, give it a name; a .o name stops at the object file:

eskiuc hello.esk -o hello && ./hello
eskiuc hello.esk -o hello.o

A struct with a method

A method is written inside the struct, or as a function Point_sum(Point* self); p.sum() calls either. A struct literal names its fields, and the ones left out start at zero.

import <io>;

struct Point {
    int x;
    int y;

    int sum() {
        return self.x + self.y;
    }
}

int main() {
    let p: Point = Point{x: 3, y: 7};
    printf("sum = %d\n", p.sum());   // sum = 10
    return 0;
}

Memory you manage

alloc<T>(n) from <mem> gives n zeroed elements of type T, and defer frees them however the function ends:

import <io>;
import <mem>;

int main() {
    *int buf = alloc<int>(4);
    defer free(buf);
    for (i in 0..4) {
        buf[i] = (i + 1) * 10;
    }
    printf("sum = %d\n", buf[0] + buf[1] + buf[2] + buf[3]);   // sum = 100
    return 0;
}

Lambdas

Functions are values. A lambda has the syntax of a function without the name:

import <io>;

int apply(fn(int)->int f, int x) {
    return f(x);
}

int main() {
    let double_it: fn(int)->int = int(int x) { return x * 2; };
    printf("%d\n", double_it(5));          // 10
    printf("%d\n", apply(double_it, 4));   // 8
    return 0;
}

A project with packages

eskiuc new makes a package, and eskiuc add brings in another one from git. A package that binds a C library downloads it on the first build:

eskiuc new myapp && cd myapp
eskiuc add onnx --git https://github.com/eskiu-lang/onnx --rev v0.1.0
eskiuc run

The packages page lists the official ones.

What's next