Eskiueskiu v0.7.0
Inicio rápido

Pon Eskiu a correr

Descarga un binario precompilado, escribe tu primer programa y córrelo. Unos cuantos minutos de principio a fin, sin toolchain que armar.

Instalación

Descarga el build de tu plataforma. La biblioteca estándar viene dentro del tarball, así que los imports jalan en cuanto lo descomprimes.

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

Windows es experimental: el compilador corre y emite objetos, pero el linking end-to-end, las excepciones y la red aún se están portando en los releases 0.7.x.

Descomprímelo en /usr/local y verifica la versión:

# macOS (Apple Silicon)
tar -xzf eskiuc-macos-arm64.tar.gz -C /usr/local

# Linux (x86-64)
tar -xzf eskiuc-linux-x86_64.tar.gz -C /usr/local

# Windows (x86-64): descomprime y agrega la carpeta bin\ al PATH
Expand-Archive eskiuc-windows-x86_64.zip -DestinationPath C:\eskiu

eskiuc --version
Eskiu 0.7.0 (LLVM ...)

El tarball instala:

El enlazado necesita un toolchain de C en tu equipo (clang o gcc), el mismo que invocan Rust y Clang para producir un binario. macOS lo trae con las herramientas de línea de comandos de Xcode; en Linux, instala build-essential (o gcc).

Hola, Eskiu

Crea hello.esk:

extern int printf(string fmt, ...);

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

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

Compílalo y córrelo de una vez. eskiuc run arma un binario nativo temporal, lo ejecuta y limpia todo al final:

eskiuc run hello.esk
Hello from Eskiu!
Result: 8

O quédate con el binario. Cuando el nombre de -o no termina en .o, eskiuc te lo enlaza como ejecutable:

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

¿Quieres solo el archivo objeto? Usa un nombre .o y enlázalo tú:

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

Un struct con un método

Los structs guardan datos. Los métodos son funciones normales que reciben un puntero al struct como primer argumento.

extern int printf(string fmt, ...);

struct Point {
    int x;
    int y;
}

int Point_sum(Point* self) {
    return self.x + self.y;
}

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

alloc / free con aritmética de punteros

alloc<T>(n) (de la stdlib <mem>) reserva n elementos de tipo T y devuelve un puntero tipado. Indexa con []. Llama a free cuando termines: la memoria corre por tu cuenta.

import <mem>;
extern int printf(string fmt, ...);

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

Lambdas

Las funciones son valores de primera clase. Una lambda se escribe con la misma sintaxis que una función normal, solo que sin nombre:

extern int printf(string fmt, ...);

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;
}

fn(int)->int es el tipo de puntero a función. La lambda int(int x) { ... } produce un valor de ese tipo.

Qué sigue