I I Language C-shaped systems programming

Language Reference

I docs

Small examples for the current language surface: C-shaped syntax, native generics, specialization, reflection, formatting, and direct C interop.

Basics

Declarations and expressions

Entry point

import "runtime/Print.i"

main: proc()->i32 = {
    printfmt("hello {}\\n", 7);
    return 0;
}

Variables

count: i32 = 4;
scale: f32 = 1.5;
name: *const char = "payload";
ready: bool = true;

Address and dereference

value: i32 = 12;
ptr: *i32 = value.&;
ptr[0] += 1;

Casts and sizes

bytes: usize = sizeof(i32) * 16;
alignment: usize = alignof(f32);
value: i32 = cast(bytes, i32);

Types

Structs, enums, aliases, arrays

Struct

Vec2: struct = {
    x: f32;
    y: f32;
}

pos: Vec2 = {.x = 10, .y = 20};

Enum

Mode: enum = {
    Idle,
    Run = 4,
    Attack,
}

mode: Mode = Mode_Attack;

Alias

CStr: alias = *const char;
Index: alias = u32;

label: CStr = "hero";
index: Index = 3;

Fixed arrays

Mesh: struct = {
    joints: [4]u16;
}

mesh: Mesh = {.joints = {[0] = 1, [3] = 9}};

Union

Value: union = {
    i: i32;
    f: f32;
}

v: Value = {.i = 42};

Const pointers

text: *const char = "read only";
bytes: *const u8 = cast(text, *const u8);

Procedures

Functions and control flow

Procedure

add: proc(a: i32, b: i32)->i32 = {
    return a + b;
}

sum: i32 = add(2, 5);

Function pointer

Callback: alias = *proc(value: i32)->i32;

apply: proc(cb: Callback, x: i32)->i32 = {
    return cb(x);
}

Loops

total: i32 = 0;
for (i: i32 = 0; i < 8; i += 1) {
    total += i;
}

Switch

switch (mode) {
    case Mode_Run:
        speed = 8;
        break;
    default:
        speed = 1;
        break;
}

Word operators

if (ready and !blocked) {
    mask = mask shl 1;
}

Call convention

WndProc: proc[WINCALL](hwnd: HWND, msg: UINT)->LRESULT = {
    return 0;
}

Generics

Monomorphized structs and procs

Generic struct

Array: struct<T> = {
    length: u64;
    border: u64;
    data: *T;
}

items: Array<i32> = {};

Generic procedure

identity: proc<T>(value: T)->T = {
    return value;
}

x: i32 = identity<i32>(9);

Namespaced generic call

Array<T>at: proc<T>(array: *Array<T>, index: u64)->*T = {
    return array[0].data + index;
}

item: *i32 = Array<i32>at(items.&, 0);

Concrete specialization

Payload: struct = {
    x: i32;
}

print: proc<Payload>(payload: Payload)->void = {
    printfmt("Payload{x: {}}", payload.x);
}

Metaprogramming

Reflection and typed formatting

Formatted printing

printfmt("x: {}, y: {}\\n", payload.x, payload.y);

The compiler lowers each value to print<T>(value).

Custom printer

print: proc<Payload>(payload: Payload)->void = {
    printfmt("Payload({}, {})", payload.x, payload.y);
}

Reflect type

name: *const char = Payload<>.name;
field_count: u64 = Payload<>.field_count;

Reflect fields

for (i: u64 = 0; i < Payload<>.field_count; i += 1) {
    printfmt("field[{}] = {}\\n", i, Payload<>.fields[i].name);
}

Requirement-style generic

need_hash: proc<T: hashable>(value: T)->u64 = {
    return hash<T>(value);
}

Typed extension point

hash: proc<Payload>(payload: Payload)->u64 = {
    return cast(payload.x, u64);
}

C Interop

Headers, macros, external symbols

C include

cinclude "stdio.h"
cinclude "windows.h"

Macro define

define("SAHA_IMPLEMENTATION")
define("gin_debug_draw")

External proc

puts: proc(text: *const char)->i32 = {
    external;
}

Emit prototype

fx_step: proc(dt: f32)->void = {
    external_emit;
}

External global

extern_ticks: u64 = { external; };

Variadic declaration

printf: proc(fmt: *const char, ...)->i32 = {
    external;
}

Runtime

Small standard library pieces

Option

opt: Option<i32> = Option<i32>some(7);
value: i32 = Option<i32>unwrap_or(opt, 0);

Result

ok: Result<i32> = Result<i32>ok(11);
failed: bool = Result<i32>is_err(ok);

Array

arr: Array<i32> = Array<i32>reserve(arena.&, 16);
arr.data[0] = 99;

Vec

vec: Vec<i32> = {};
Vec<i32>append(arena.&, vec.&, 5);

Map

map: *Map<i32> = Map<i32>create(arena.&);
Map<i32>set(arena.&, map, "hp", 100);

Print

print<i32>(7);
print_cstr("\\n");
printfmt("{}", 7);

Compiler

CLI and editor support

Compile

build\I.exe compile src\main.i -o build\main.c

Check

build\I.exe check src\main.i --diagnostics=json

Symbols

build\I.exe symbols src\main.i --format=json

LSP

build\I.exe lsp src\main.i --format=json