Memory Model
Value Types
- Scalars
- Structs
- Fixed arrays
- vec2, vec3, vec4
- mat2, mat3, mat4
Stored directly on stack or inline.
Reference Types
- str
- array
<T>{=html}
These may allocate memory internally.
Memory Rules
- No garbage collector
- No hidden allocations
array<T>auto-initializes on declaration; call.free()to release memory- Struct layout is C-compatible
Slice Model
[]T is a fat pointer — { void* ptr; int64_t len; }. It views contiguous data without owning it. Fixed arrays (T[N]) and dynamic arrays (array<T>) implicitly convert to slices.
var arr: i32[5] = {10, 20, 30, 40, 50};
var s: []i32 = arr; // zero-cost: just takes pointer + length
s[1:3] // subslice: zero-copy view
String Model
str is a fat string — a { ptr, len } pair that carries the byte length alongside the pointer. Strings are UTF-8 and immutable.
var s:str = "hello"
s.len // 5 — O(1), no scanning
s.cstr // raw const char* for C interop
s.ptr // same as .cstr
String comparison is value-based (not pointer comparison):
var a:str = "hello"
var b:str = "hello"
if (a == b) { /* true — compares content, not pointers */ }
Use .str() for numeric conversion:
var i = 42
print(i.str())
Built-in String Methods
| Method | Returns | Allocates? | Description |
|---|---|---|---|
.find(needle) | i64 | No | First byte index of needle, or -1 |
.find_last(needle) | i64 | No | Last byte index of needle, or -1 |
.contains(needle) | bool | No | Whether string contains needle |
.starts_with(prefix) | bool | No | Whether string starts with prefix |
.ends_with(suffix) | bool | No | Whether string ends with suffix |
.count(needle) | i64 | No | Count non-overlapping occurrences |
.sub(start, len) | str | No | Zero-copy substring (len optional) |
.trim() | str | No | Trim whitespace both sides |
.trim_left() | str | No | Trim leading whitespace |
.trim_right() | str | No | Trim trailing whitespace |
.upper() | str | Scratch | ASCII uppercase |
.lower() | str | Scratch | ASCII lowercase |
.replace(old, new) | str | Scratch | Replace all occurrences |
.repeat(n) | str | Scratch | Repeat string n times |
.split(delim) | str[] | Scratch | Split by delimiter |
Zero-copy methods (find, sub, trim, etc.) return a str that points into the original string’s memory — just adjusting ptr and len. No allocation occurs.
Scratch methods (upper, lower, replace, repeat, split) write into the runtime’s rotating scratch buffer (16 slots x 1KB). This avoids heap allocation but means results are temporary — assign to a variable before calling another scratch method if you need to keep the result.
To pass str to C functions that expect const char*, use the cstr type. The compiler auto-converts between str and cstr at function boundaries:
- Passing
strto extern fn(cstr) → auto-extracts.ptr - Passing
cstrto fn(str) / print() → auto-wraps with length