Sterling Language Documentation

Version: 0.1.0-alpha

Overview

Sterling is a low-level, strongly typed, systems programming language designed for performance, ABI stability, C interoperability, and full control over memory and hardware. It supports metaprogramming, hot-reloading, inline and raw assembly, and is built for multi-file compilation. It also introduces memory safety primitives and modern low-abstraction control flow enhancements.

This Document is a work in progress, features are not yet implemented and i use this as a design document to stay true to my vision

File Extensions (placeholder, subject to change)

Function Qualifiers

Every function must declare its linkage explicitly:


fn		// globally visible, default linkage
fn_static	// translation unit-local only
fn_inline	// inline-only, no symbol emitted
fn_asm		// raw assembly function, globally visible
fn_static_asm	// raw assembly function, TU-local only

Function Syntax

All functions must explicitly declare their return type. The only exception is void, which may be omitted for brevity when no return value is intended.


fn u32 add(u32 a, u32 b) {
	return (a + b);
}

fn_extern i32 printf(const char* fmt, ...);

fn_inline u32 max(u32 a, u32 b) {
	return ((a > b) ? a : b);
}

fn exit() {
	// equivalent to fn void exit()
}

Assembly Functions

Write raw x86_64 assembly using fn_asm or fn_static_asm. Symbol, section, and global declaration are implicit.


fn_asm void* memset(void* dst, u8 value, u64 size) {
	test rdx, rdx
	je .done

	mov rax, rsi
	mov rdi, rdi
	mov rcx, rdx

	rep stosb

.done:
	mov rax, rdi
	ret
}

Syscalls

System calls are allowed via fn_asm or wrapped using concrete ABI-aware interfaces. Example:


fn_asm void exit() {
	mov rax, 60   ; syscall: exit
	mov rdi, 0    ; exit code
	syscall
	ret
}

Types

Sterling supports explicitly sized, ABI-stable primitive types. Signed and unsigned integer types are defined as follows:


i8, i16, i32, i64	// signed integers
u8, u16, u32, u64	// unsigned integers
f32, f64		// 32-bit and 64-bit IEEE floats
bool			// 1-byte boolean, 0 or 1 only
char			// 1-byte character (UTF-8)

Pointer types:


T*	// Pointer to type T
ptr*	// Special pointer with implicit coercion allowed (e.g., for GC, reflective systems)
void*	// Opaque pointer with explicit cast required

All types have explicitly defined size and alignment. Structs support default values and zero-initialization rules:


typedef struct {
	u32 x = 5;
	u32 y;
} vec2u;

vec2u a = {};	// x = 5, y = 0
vec2u b = {0};	// x = 0, y = 0
vec2u c;	// x = 0, y = 0 (default zero-init)

To opt out of default zero-initialization:


@raw u32 raw_val; // uninitialized

Memory Model

Sterling uses explicit, manual memory management by default. All variables are zero-initialized unless explicitly marked with @raw. Heap allocation is done via standard system or custom allocators.

Alignment and packing are controllable per type (TBD syntax). All layout is predictable and optimized for cache behavior. There are no hidden fields, vtables, or RTTI overhead.

Operating System Development Features

Metaprogramming

TODO: Describe 'meta' keyword, templating, compile-time codegen, restrictions on type inference.

ABI and Interop

TODO: Specify ABI model (System V AMD64), calling convention details, struct/pointer representation rules.

Threading

TODO: Describe standard threading model, scheduler integration, context switching, green threads API.

Graphics and Rendering

TODO: Describe native rendering interface, GPU abstraction layer, and access to OpenGL/DirectX backends.

Build and Compilation Model

TODO: AOT compilation, linker behavior, multi-file project structure, module system (if any).

Function Syntax

Return types are mandatory and must be declared explicitly. The only exception is void, which can be omitted as it represents no return value.


fn u32 add(u32 a, u32 b) {
	return a + b;
}

fn_extern i32 printf(const char* fmt, ...);

fn_inline u32 max(u32 a, u32 b) {
	return (a > b) ? a : b;
}

fn exit() {
	// equivalent to fn void exit()
}

Assembly Functions

Write raw x86_64 assembly using fn_asm or fn_static_asm. Symbol, section, and global declarations are implicit.


fn_asm void* memset(void* dst, u8 value, u64 size) {
	test rdx, rdx
	je .done

	mov rax, rsi
	mov rdi, rdi
	mov rcx, rdx

	rep stosb

.done:
	mov rax, rdi
	ret
}

Syscalls

System calls can be issued directly using fn_asm. Wrappers may be defined for ABI-safe interfaces.


fn_asm void exit() {
	mov rax, 60   ; syscall: exit
	mov rdi, 0    ; exit code
	syscall
	ret
}

Types


i8, i16, i32, i64     // signed integers
u8, u16, u32, u64     // unsigned integers
f32, f64              // IEEE floats
bool                  // 1-byte boolean
char                  // UTF-8 byte

Pointer types:


T*         // pointer to T
ptr*       // special pointer with implicit coercion
void*      // opaque pointer, explicit cast only

Structs support defaults and zero-initialization:


typedef struct {
	u32 x = 5;
	u32 y;
} vec2u;

vec2u a = {};      // x = 5, y = 0
vec2u b = {0};     // x = 0, y = 0
vec2u c;           // x = 0, y = 0 (default)

u32 raw @raw; // opt-out of zero-init

Memory Model

Arrays, strings, and bitfields are memory-safe by default with bounds-aware utility functions and type traits.

Metaprogramming


meta define_add(T);
T add(T a, T b) {
	return a + b;
}

Only primitive types are allowed without explicit overloads. Structs must implement meta_add manually. Compile-time execution is guaranteed only for pure expressions.

Control Flow Extensions

Designed for structured, optimized low-level behavior:


match_const value {
	0b0000: return EMPTY;
	0b0001: return CORNER;
	...
}

fallthrough_block(value) {
	0b0011: case_edge;
	0b1010: case_edge;

	label case_edge:
		// handle edge
		break;
}

loop_outer: while (true) {
	loop_inner: while (true) {
		if (x) break loop_outer;
	}
}

Bitfields and Bit Types

Sterling supports bit and bitfield types to define compact data structures. Useful for efficient array storage, runtime layout configuration, and manual control of field width.


bitfield struct TileMask {
	bit corner : 1;
	bit edge   : 1;
	bit fill   : 1;
	...
}

Memory-Aware Structures

Sterling provides tools to construct layout-aware containers like aligned arrays, flexible bitfield arrays, and layout-optimized structures that adjust at runtime.

Nested Loop Control

Use labeled loop exits or control redirection to break from specific nesting levels without deep stacks:


while (game_running) {
	while (update_running) {
		if (exit_to_game) break @2;
	}
}

Threading

TODO: Specify green threading model, context switch ABI, thread-local storage and atomic operations.

ABI and Interop

Sterling uses the System V AMD64 ABI. C interop requires exact type and calling signature match. All exported symbols must declare calling convention and linkage explicitly. Casts must be intentional. fn test() -> i32 syntax is not supported; return type must be declared in C form as fn i32 test().

Build and Compilation

TODO: Describe Sterling to C translation, compiler phases, linking steps, macro expansion and preprocessing rules.

Sterling Language Documentation

Sterling Language Documentation

Version: 0.1.0-alpha

Overview

Sterling is a low-level, strongly typed, systems programming language designed for performance, ABI stability, C interoperability, and full control over memory and hardware. It supports metaprogramming, hot-reloading, inline and raw assembly, and is built for multi-file compilation.

File Extensions

Function Qualifiers

Every function must declare its linkage explicitly:

fn               // globally visible, default linkage
fn_static        // translation unit-local only
fn_inline        // inline-only, no symbol emitted
fn_asm           // raw assembly function, globally visible
fn_static_asm    // raw assembly function, TU-local only

Function Syntax

All functions must explicitly declare their return type. The only exception is void, which may be omitted for brevity when no return value is intended.

fn u32 add(u32 a, u32 b) {
	return a + b;
}

fn_inline u32 max(u32 a, u32 b) {
	return (a > b) ? a : b;
}

fn exit() {
	// equivalent to fn void exit()
}

Assembly Functions

Write raw x86_64 assembly using fn_asm or fn_static_asm. Symbol, section, and global declaration are implicit.

fn_asm void* memset(void* dst, u8 value, u64 size) {
	test rdx, rdx
	je .done

	mov rax, rsi
	mov rdi, rdi
	mov rcx, rdx

	rep stosb

.done:
	mov rax, rdi
	ret
}

Syscalls

System calls are allowed via fn_asm or wrapped using concrete ABI-aware interfaces. Example:

fn_asm void exit() {
	mov rax, 60   ; syscall: exit
	mov rdi, 0    ; exit code
	syscall
	ret
}

Register Access

Sterling exposes raw CPU registers as language-level primitives. This is intended for kernel, embedded, and runtime-critical tasks.

fn u64 get_rbp() {
	return rbp;
}

fn void set_rsp(u64 val) {
	rsp = val;
}

Supported registers: rax, rbx, rcx, rdx, rsi, rdi, rsp, rbp, r8..r15. Usage outside permitted contexts may trigger compile-time errors. Clobber rules and calling conventions must be respected.

Types

Sterling supports explicitly sized, ABI-stable primitive types. Signed and unsigned integer types are defined as follows:

i8, i16, i32, i64     // signed integers
u8, u16, u32, u64     // unsigned integers
f32, f64              // 32-bit and 64-bit IEEE floats
bool                  // 1-byte boolean, 0 or 1 only
char                  // 1-byte character (UTF-8)

Pointer types:

T*         // Pointer to type T
ptr*       // Special pointer with implicit coercion allowed (e.g., for GC, reflective systems)
void*      // Opaque pointer with explicit cast required

All types have explicitly defined size and alignment. Structs support default values and zero-initialization rules:

typedef struct {
	u32 x = 5;
	u32 y;
} vec2u;

vec2u a = {};      // x = 5, y = 0
vec2u b = {0};     // x = 0, y = 0
vec2u c;           // x = 0, y = 0 (default zero-init)

To opt out of default zero-initialization:

u32 raw_val @raw; // uninitialized

Memory Model

Sterling uses explicit, manual memory management by default. All variables are zero-initialized unless explicitly marked with @raw. Heap allocation is done via standard system or custom allocators.

Alignment and packing are controllable per type (TBD syntax). All layout is predictable and optimized for cache behavior. There are no hidden fields, vtables, or RTTI overhead.

Metaprogramming

TODO: Describe 'meta' keyword, templating, compile-time codegen, restrictions on type inference.

ABI and Interop

TODO: Specify ABI model (System V AMD64), calling convention details, struct/pointer representation rules.

Threading

TODO: Describe standard threading model, scheduler integration, context switching, green threads API.

Graphics and Rendering

TODO: Describe native rendering interface, GPU abstraction layer, and access to OpenGL/DirectX backends.

Build and Compilation Model

TODO: AOT compilation, linker behavior, multi-file project structure.