Zwykła fun kompiluje się
do prawdziwego Rusta.
HackerScript to język ogólnego przeznaczenia: statyczne typy i bezpieczeństwo pamięci Rusta na co dzień, z direct [ ... ] jako ucieczką do czystego Pythona dla małych fragmentów, które nigdy nie będą wymagały wydajności.
struct Point [
x: Int,
y: Int
]
fun distance_squared(p: Point) -> Int [
end (p.x * p.x) + (p.y * p.y)
]
fun main() [
let p = Point(3, 4)
log("dist^2 =", distance_squared(p))
direct [
print("To jest czysty Python wewnątrz binarki Rust.")
]
end
]
Wprowadzenie
fun → hackerc generuje prawdziwy Rust: struct staje się struct + impl new(), manual [...] staje się unsafe { ... }, List<T> staje się Vec<T>. Parametry typu struct/List/Str automatycznie dostają &/&mut zamiast przenoszenia własności.
direct [ ... ] → surowy Python wykonywany w trakcie działania programu przez Python::with_gil (PyO3, tryb auto-initialize) — Rust jest hostem.
Statyczne typy
Cały front — lexer/parser/typecheck/typeinfer — jest sam napisany w HackerScript.
Zero-cost
Kompilacja do Rusta oznacza brak własnego runtime'u ponad to, co daje rustc.
Self-hosted
hackerc i virus są dziś w całości napisane w samym HackerScript (.hcs).
Instalacja
hackerc i virus to binarki natywne (self-hosted) — najprościej pobrać gotowe wydanie.
curl -L --fail -o hackerc \
https://github.com/HackerOS-Linux-System/HackerScript/releases/download/v0.1/hackerc
chmod +x hackerc
./hackerc check docs/hello-world/Virus.hk
./hackerc build docs/hello-world/cmd/main.hcs -o /tmp/out
cd /tmp/out && cargo run # wymaga zainstalowanego Rusta
using <wersja> na początku pliku (lub [package] using w Virus.hk) deklaruje wymaganą wersję hackerc — jeśli nie jest zainstalowana, virus pobiera ją automatycznie z GitHub Releases.Pierwszy projekt
W projekcie zarządzanym przez virus (patrz Virus.hk):
virus init --name moj-projekt
cd moj-projekt
virus build --release # pobierze właściwy hackerc automatycznie
Zmienne i typy
let x = 5
const PI = 3.14159
let lista: List<Int> = [1, 2, 3]
let wynik: Result<Int, Str> = ok(42)
let moze: Option<Int> = some(7)
| Typ | Znaczenie |
|---|---|
Int / Float / Str / Bool / Void | typy podstawowe |
List<T> | lista, transpilowana do Vec<T> |
Dict<K, V> | mapa (dziś: bez iteracji for k, v in ... — patrz Roadmap) |
Option<T> | some(x) / none() |
Result<T, E> | ok(x) / err(e) |
Funkcje
end <wyrażenie> zwraca wartość i kończy funkcję. Ostatnie wyrażenie w bloku nie jest niejawnie zwracane — end jest zawsze wymagane, żeby coś zwrócić.
fun fib(n: Int) -> Int [
if n <= 1 [
end n
]
end fib(n - 1) + fib(n - 2)
]
Struktury i impl
struct Point [
x: Int,
y: Int
]
impl Point [
fun sum(self) -> Int [
end self.x + self.y
]
]
let p = Point(1, 2)
log(p.sum())
Generyczne deklaracje struct Box<T> / fun map<T,U> jeszcze nie istnieją planowane — List<T>/Dict<K,V> działają jako użycie generyków, nie deklaracja własnych.
Enum i match
enum Shape [
Circle(Float),
Rectangle(Float, Float),
Empty
]
fun area(s: Shape) -> Float [
match s [
Circle(r) -> [ end 3.14159 * r * r ]
Rectangle(w, h) -> [ end w * h ]
_ -> [ end 0.0 ]
]
]
Sterowanie przepływem
if n > 0 [
log("dodatnie")
] elif n < 0 [
log("ujemne")
] else [
log("zero")
]
let i = 0
while i < 5 [
log(i)
i = i + 1
]
for jezyk in ["Python", "Rust", "HackerScript"] [
log(jezyk)
]
direct i manual
direct [ ... ] uruchamia surowy Python w trakcie działania programu (PyO3). manual [ ... ] transpiluje się do unsafe { ... } w wygenerowanym Ruście — do użycia świadomie.
native {JavaScript}
Statycznie linkowany silnik JS — QuickJS przez rquickjs (kompilowany przez cc, nie zewnętrzny interpreter). console.log(...) jest polyfillem dopisywanym przez kompilator.
native {JavaScript} [
const dane = { jezyk: "JavaScript", dziala: true };
console.log(JSON.stringify(dane));
]
// import zewnetrznego pliku (sciezka wzgledna do .hcs)
native {JavaScript} <lib/utils.js> [
console.log(funkcjaZUtilsJs());
]
Dziś tylko silnik "JavaScript" — inna nazwa daje komentarz, bez błędu kompilacji.
$ polecenie $ — Zero-Cost Sandbox
Uruchamia polecenie powłoki w izolacji sieci i systemu plików przez libc::unshare(CLONE_NEWNET|CLONE_NEWNS) + bind-remount / na read-only — zero zewnętrznych narzędzi (firejail/bwrap). Brak uprawnień → ostrzeżenie na stderr, polecenie i tak działa, ale bez izolacji (nigdy cichy fejl).
$
whoami
echo "brak dostepu do sieci hosta i zapisu do /"
$
$ (np. $HOME) — zamyka blok na pierwszym napotkanym.@hot_reload — podmiana kodu żywego procesu
Funkcja oznaczona @hot_reload trafia do osobnego, dynamicznie ładowanego cdylib. Wątek-obserwator śledzi plik .hcs i przy zmianie sam woła hackerc build + cargo build --release, po czym atomowo podmienia wskaźnik funkcji w działającym procesie — bez restartu.
@hot_reload
fun greet() [
log("wersja 1")
end
]
HKS_HOT_OUT_DIR przy uruchomieniu (jawny błąd, jeśli brak) i ręcznego pierwszego builda hotlib/.System modułów (get)
get <core:memory::arena> import <arena_new::arena_alloc::arena_get>
get <std:path> import <path_join>
get <crates:serde> ! prawdziwa zależność Cargo
get <pypi:nazwa> ! pobierane przez virus install
| Prefiks | Źródło |
|---|---|
std: / core: | libs/std/lib/ / libs/core/lib/ w tym repozytorium |
crates: | prawdziwa zależność Cargo |
pypi: / npm: / jsr: | pobierane bezpośrednio przez virus install, bez pip/npm install |
vira: | oficjalny rejestr vira.io |
Virus.hk
Format .hk manifestu projektu — nie TOML, mimo podobnego wyglądu.
[package]
name = "hello-world"
version = "0.0.1"
using = "0.1"
edition = "2026"
authors = ["Twoje Imię"]
[dependencies]
# "pypi:rich" = "*"
[build]
entry = "cmd/main.hcs"
CLI: hackerc i virus
| Komenda | Co robi |
|---|---|
hackerc check plik.hcs | parsuje + typechecking, bez generowania Rusta |
hackerc build plik.hcs -o dir | generuje crate Cargo w dir |
virus init --name x | tworzy nowy projekt z Virus.hk |
virus build --release | pobiera właściwy hackerc wg using, buduje |
virus install <pakiet> | pobiera zależność z PyPI/crates.io/npm/JSR/Vira |
virus fmt [--check] | formatuje (lub sprawdza formatowanie) plików .hcs |
virus lint | uruchamia diagnostyki hackerc na projekcie |
Kolorowe wyjście (zielony = sukces, czerwony = błąd, cyan = nazwy) wyłącza się automatycznie, gdy ustawiona jest zmienna środowiskowa NO_COLOR.
Biblioteka standardowa
fs / io / path
System plików, wejście-wyjście, operacje na ścieżkach.
string / math
Operacje tekstowe i matematyczne.
json / toml / hk
Parsery formatów danych, w tym własnego formatu manifestu.
http / process / env
Zapytania HTTP, uruchamianie poleceń, zmienne środowiskowe.
term
Kolorowe CLI i pasek postępu renderowany w miejscu.
result
Pomocnicze funkcje dla Result<T,E>.
cybersecurity
constant_time_eq, shannon_entropy.
core/memory
Cztery alokatory: arena, chained_arena, stack_allocator, pool_allocator.
Roadmap
Pełna, szczegółowa wersja: docs/ROADMAP.md w repozytorium. Skrót stanu:
| Funkcja | Status |
|---|---|
direct [ ... ] (Python przez PyO3) | naprawione i zweryfikowane |
native {JavaScript} [ ... ] (QuickJS, statyczne linkowanie) | nowe, zweryfikowane |
native {JavaScript} <plik.js> (import) | nowe, zweryfikowane |
$ polecenie $ (Zero-Cost Sandbox) | nowe, zweryfikowane |
@hot_reload (podmiana kodu żywego procesu) | nowe, zweryfikowane |
get <crates:nazwa::wersja> | działa, zweryfikowane |
get <pypi:nazwa> (tylko wewnątrz direct) | działa, zweryfikowane |
get <npm:...> / get <jsr:...> | tylko komentarz, bez importu |
virus install (realne pobieranie) | niezweryfikowane w tym środowisku |
| Linia/kolumna w błędach parsera | naprawione i zweryfikowane |
Numery linii w węzłach AST (dla typecheck.hcs) | planowane |
Iteracja po Dict | planowane |
Typ Set<T> | planowane |
log() dla struct/enum | częściowe |
Generyczne fun<T> / struct<T> | planowane |
| Trait / interface | planowane |
virus test + #[test] | planowane |
| REPL | planowane |
| LSP | planowane |
Checksumy/lockfile w virus install | planowane |
| Backend Cranelift | zdjęte z planów |