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

MethodReturnsAllocates?Description
.find(needle)i64NoFirst byte index of needle, or -1
.find_last(needle)i64NoLast byte index of needle, or -1
.contains(needle)boolNoWhether string contains needle
.starts_with(prefix)boolNoWhether string starts with prefix
.ends_with(suffix)boolNoWhether string ends with suffix
.count(needle)i64NoCount non-overlapping occurrences
.sub(start, len)strNoZero-copy substring (len optional)
.trim()strNoTrim whitespace both sides
.trim_left()strNoTrim leading whitespace
.trim_right()strNoTrim trailing whitespace
.upper()strScratchASCII uppercase
.lower()strScratchASCII lowercase
.replace(old, new)strScratchReplace all occurrences
.repeat(n)strScratchRepeat string n times
.split(delim)str[]ScratchSplit 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 str to extern fn(cstr) → auto-extracts .ptr
  • Passing cstr to fn(str) / print() → auto-wraps with length