Iskra
Overview
Iskra was designed for a concrete machine environment rather than as a syntax exercise. Its programs become static x86-64 ELF executables that Vostok can validate, map into private address spaces and run as isolated processes.
The host compiler already builds the operating system’s userspace: init, the shell, console service and supporting programs. This gives every language feature a practical test. A type, calling convention or layout rule is only useful when code generated from it survives a real kernel boundary.
The language and its operating system share one machine model.
Language subset
The 0.1 language is deliberately compact. It provides signed and unsigned integers from 8 to 64 bits, usize, isize, booleans, functions, local scopes, constants, structures, explicit pointers and fixed arrays. Control flow is built from if, else and while.
struct Point {
x: i64,
y: i64,
}
fn distance_squared(point: *const Point) -> i64 {
let x = point.x;
let y = point.y;
return x * x + y * y;
}
Mutation is visible: let creates an immutable binding and var creates a mutable one. Numeric conversions require as; integers do not silently become booleans. Every field in a structure literal must be initialised exactly once, and fixed-array indexing emits a runtime bounds trap.
Iskra is not memory safe. Raw pointer validity remains the program’s responsibility, and the language does not present pointers as ownership-checked references. That boundary is stated directly instead of suggesting guarantees the compiler does not provide.
Compiler architecture
The host compiler is written in C and exposes each major stage for inspection:
source → lexer → parser → AST
→ semantic analysis → typed HIR
→ x86-64 assembly → static ELF64
Lexer and parser
The lexer retains file, line and column data for every token. Statements and declarations use recursive descent; expressions use a Pratt parser so precedence and associativity are handled in one explicit table.
The compiler can dump its tokens and AST independently. These are development interfaces as much as debugging commands: they make it possible to verify where syntax stops and meaning begins.
Semantic analysis and typed HIR
Semantic analysis resolves names and checks types, mutability, calls, conditions and return paths. The resulting HIR stores resolved bindings and the type of each expression, so the backend does not have to rediscover language rules while emitting instructions.
If semantic checking fails, code generation does not run. Diagnostics carry the filename, one-based line and column, a stable lex, parse or semantic category, and the relevant source line when available.
x86-64 backend
The backend emits GNU x86-64 assembly. The host build then uses the GNU assembler and linker to produce a static ELF64 executable for Vostok.
There is no machine IR, register allocator or optimisation pipeline yet. The direct backend keeps the relationship between typed operations and emitted instructions visible while the language and ABI are still being established.
Vostok ABI
The target is named x86_64-unknown-vostok. Version 0.1 follows the integer portion of the System V AMD64 calling convention: the first arguments use rdi, rsi, rdx, rcx, r8 and r9; scalar results return through rax; and the stack is aligned to 16 bytes before a call.
The target deliberately has no red zone. Structure fields retain declaration order with natural padding, and layout does not depend on optimisation. Ordinary Iskra functions use deterministic symbol mangling, while extern fn preserves the written name for linkage with the runtime.
A Vostok process enters through _start, which establishes the ABI state, preserves bootstrap capability handles, calls the Iskra main function and forwards its result to the process-exit syscall. Runtime wrappers expose IPC, capabilities, files, process control and console access across interrupt vector 0x80.
Native bootstrap compiler
The host compiler is the complete implementation used to build Vostok userspace. Vostok also contains a much smaller compiler written in Iskra itself. That native compiler runs as an ordinary ring-3 process, reads source through a filesystem capability and writes /home/a.out directly to ramfs.
The native version currently accepts a narrow bootstrap program rather than the complete language. It proves that compilation can happen inside the target system; it is not presented as full self-hosting.
Testing
The test suite covers tokenisation, parsing, semantic rejection, diagnostics, structures, pointers, strings, arrays, control flow, arithmetic and generated machine code. Compiler dumps are deterministic, which makes changes to tokens, AST and typed HIR reviewable.
The boundary test happens in Vostok’s QEMU suite. Iskra-generated ELF programs are loaded by the real kernel and exercised as ring-3 processes. This catches disagreements in calling convention, process entry, runtime wrappers and ELF layout that compiler-only tests cannot see.
Current limitations
Iskra remains a bootstrap systems language. It does not yet include modules, imports, generics, slices, heap allocation, ownership checking, floating point, concurrency, exceptions, macros or a standard library. The compiler has no CFG or SSA passes, machine IR, register allocation, direct object output or native linker.
Those omissions keep version 0.1 coherent: a small language, a documented ABI and a compiler capable of producing the real userspace of its target operating system.