Getting started
Halis installs with one command. The release archive carries the whole
toolchain — the compiler hlc and the formatter hlfmt as binaries, the
standard library std/ and the freestanding runtime core/ as source — so
you need no C compiler, no make and no Python.
curl -fsSL https://raw.githubusercontent.com/mhieuhonda/halis-lang/main/install.sh | shThe installer picks the archive matching your platform, verifies its SHA-256
against the release’s own SHA256SUMS before unpacking anything, installs
into /usr/local (or ~/.local if that is not writable), and then runs its
own acceptance gate: it compiles a program that imports std.result and
formats that program twice — the second pass must equal the first.
Your first program
Section titled “Your first program”Create hello.hls:
fn greet(name: str) -> str { return "Hello, " + name + "!"}
fn main() -> int uses IO { println(greet("Halis")) println("A high-security programming language, compiled native.") println("Compiled by a compiler written in HLS itself.") return 0}Two things are already different from most languages:
greethas nousesclause, so the compiler guarantees it is pure.maindeclaresuses IO— without it, the call toprintlnis a compile error, not a warning.
Build and run
Section titled “Build and run”hlc emits C, and the system C compiler turns that into a native binary:
hlc hello.hls hello.ccc -o hello hello.c -lm -pthread./helloCheck without running
Section titled “Check without running”hlc --check hello.hls--check type-checks and effect-checks the program without emitting code. It
is the fastest way to see the effect error message:
error: function 'main' calls 'println' which requires effect 'IO'not declared (declared: (none - pure); missing: IO)See the proof
Section titled “See the proof”hlc --audit hello.hls--audit prints, for every function, the capabilities it declared and the
capabilities the compiler computed by walking the call graph. A function
that declares nothing and computes nothing is proven pure; a mismatch is a
violation with the offending call chain named.
Everyday commands
Section titled “Everyday commands”| Command | What it does |
|---|---|
hlc prog.hls prog.c |
Compile HLS to C |
hlc --check prog.hls |
Type- and effect-check without generating code |
hlc --audit prog.hls |
Print the capability and taint-flow report |
hlc --emit llvm prog.hls out.ll |
Emit LLVM IR instead of C |
hlc --sandbox DIR prog.hls |
Confine file builtins to DIR |
hlfmt -w prog.hls |
Format the file in place |
hllint prog.hls |
Run the safety-first linter |
hltest |
Run the in-language test suite |
Building from a source checkout
Section titled “Building from a source checkout”If you want to work on the compiler itself, or you are on a platform without a prebuilt archive:
git clone https://github.com/mhieuhonda/halis-lang.gitcd halis-langmake bootstrap # ~20 s: cc builds the committed snapshot, HLS takes overmake run F=examples/hello.hlsmake testmake bootstrap compiles the committed C snapshot and then requires the
freshly built compiler to re-derive that snapshot byte for byte. A stale
or hand-edited snapshot fails the build loudly. See
the bootstrap law.
Editor support
Section titled “Editor support”The VS Code extension lives in editors/vscode/halis/ and bundles the
language server, the formatter, the linter and the debug adapter. Neovim
syntax and plugin files are in editors/neovim/.