Descarga un binario precompilado, escribe tu primer programa y córrelo. Unos cuantos minutos de principio a fin, sin toolchain que armar.
Descarga el build de tu plataforma. La biblioteca estándar viene dentro del tarball, así que los imports jalan en cuanto lo descomprimes.
Windows está validado en un runner nativo de CI: el compilador compila y enlaza, y las excepciones junto con las pilas de red bloqueante y async pasan end to end. Todavía no bloquea los releases, así que la descarga sigue marcada como experimental.
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.8.0 (LLVM ...)
El tarball instala:
bin/eskiuc: el compiladorlib/eskiu/stdlib/: la biblioteca estándar
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).
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
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<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;
}
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.