Forge has a static type system with explicit annotations and inference for literals.
| Type | Aliases | Size | Range |
|---|---|---|---|
int8 |
i8 |
8-bit signed | -128 to 127 |
int16 |
i16 |
16-bit signed | -32,768 to 32,767 |
int32 |
i32, int |
32-bit signed | -2^31 to 2^31-1 |
int64 |
i64 |
64-bit signed | -2^63 to 2^63-1 |
uint8 |
u8, byte |
8-bit unsigned | 0 to 255 |
uint16 |
u16 |
16-bit unsigned | 0 to 65,535 |
uint32 |
u32, uint |
32-bit unsigned | 0 to 2^32-1 |
uint64 |
u64 |
64-bit unsigned | 0 to 2^64-1 |
usize |
— | pointer-sized unsigned (maps to uint64) |
platform-dependent |
isize |
— | pointer-sized signed (maps to int64) |
platform-dependent |
int128/uint128are accepted by the type checker but unsupported by all backends — compilation fails at codegen. See Known Issues.
| Type | Aliases | Size | Notes |
|---|---|---|---|
float32 |
f32 |
32-bit | IEEE 754 single; x86_64 only |
float64 |
f64, float |
64-bit | IEEE 754 double; x86_64 only |
Floats are not supported on the x86_32 target. On x86_64, float values are stored as 64-bit integer bit patterns in registers.
| Type | Description |
|---|---|
bool |
true or false |
char |
8-bit character (like a byte) |
void |
No value (function return type only) |
ptr[T] # Pointer to T
let x: int32 = 42
let p: ptr[int32] = &x # Address of a local
let q = 0x1000 as ptr[int32] # Integer literal as pointer
Pointers:
&local, integer casts, alloc(), or string literals (ptr[char])*p) and pointer arithmetic (p + n) require unsafe&x is implicitly coerced to ptr[T] when passed as a function argumentasThere is no separate mut ptr[T] spelling — mutability is expressed with
var bindings and enforced by the unsafe rules.
struct Point:
x: int32
y: int32
Point { x: 1, y: 2 }p.x where p: ptr[Point]struct Pair[T]:
first: T
second: T
Generic structs are instantiated with a type application and monomorphized per instantiation:
var p: Pair[int64] = Pair[int64] { first: 3, second: 4 }
var q: Pair[Pair[int64]] = Pair[Pair[int64]] { first: p, second: p }
Pair[int64, f64]Pair[Pair[int64]]var t: T, Pair[T] { ... }) — the concrete instance is
resolved at the call sitePair$i64); a generic struct with no remaining type
parameters is equivalent to a plain structlet arr = [1, 2, 3] # Array literal
let x = arr[0]
Array literals and indexing work. Fixed-size type annotations
([int32; 5]) and repeat literals ([0; 3]) are not supported yet.
let t: (int64, int64) = (3, 4)
let a = t.0 # Field access by index
var (x, y) = t # Destructuring
Tuples work end-to-end on x86_64 and x86_32: literals, type annotations,
indexed field access (t.0, t.1), destructuring, and tuple return
types (def pair() -> (int64, int64)).
enum Color:
Red
Green
Blue
enum declarations are fully supported. Variants can be constructed
(Color.Red, Option.Some(42)), matched on with match/case, and
destructured to bind payload values (case Option.Some(x):). See
Control Flow › Match Expression for details.
union declarations are accepted by the parser and type checker, but cannot be
constructed — codegen support is not yet implemented. See
Known Issues.
Types are inferred when possible:
let x = 42 # int32 (default integer)
let y = 3.14 # float64 (default float)
let z = true # bool
let s = "hello" # ptr[char] (string literal)
Explicit annotation is used when needed:
let x: int64 = 42
let f: float64 = 1.5
There are no implicit numeric conversions — explicit as casts are required:
let y = x as int64 # Integer widening/narrowing
let f = 42 as float64 # Integer to float
let i = 3.7 as int32 # Float to integer (truncating)
let p = 0x1000 as ptr[int32] # Integer to pointer
let addr = p as int64 # Pointer to integer
let size = sizeof(u32) # Size of a type in bytes
let size2 = sizeof(MyStruct)
let off = offsetof(Point, y) # Byte offset of a field
Both return usize-typed values and work on primitives and struct types.
The following type forms parse but are not functional yet — see Known Issues:
ref[T] / refmut[T] — references (only ref[T] annotation + deref work)own[T] — owned pointers (declaration only; no constructor)[T; N] — fixed-size array annotationsslice[T] — slicesfn(T) -> T — function types