Primitive Types

Integer types

TypeSizeRange
i81 byte-128 to 127
i162 bytes-32,768 to 32,767
i324 bytes-2B to 2B
i648 bytesFull 64-bit signed
u81 byte0 to 255
u162 bytes0 to 65,535
u324 bytes0 to 4B
u648 bytesFull 64-bit unsigned

Aliases: int = i64, uint = u64, byte = u8

A value always stays in its type’s range: arithmetic on a u8 gives a u8 that wraps at 256, an i32 wraps at 2^31, and storing a wider value into a narrow variable wraps it (see Operators). @sizeof(T) and @alignof(T) give a type’s size and alignment at runtime too.

Floating point

TypeSizePrecision
f324 bytes~7 decimal digits
f648 bytes~15 decimal digits

Alias: float = f64

A float literal is an f64, except next to an f32: x * 2.0 with x: f32 is an f32. An f32 meeting an f64 value widens to f64. An f32 stored into an f64 (variable, parameter, return value) widens exactly; a typed f64 stored into an f32 is a compile error until the rounding is written: let y: f32 = x; with x: f64 is “‘y’ is f32, given f64: convert with ‘as’ (x as f32)”; write x as f32. A float literal, or an expression of them (1.0 / 3.0), needs no as.

Boolean

tape
let flag: bool = true;
let done: bool = false;

String

tape
let greeting: string = "Hello, world!";

Strings are owned UTF-8 sequences in t1/t2. In t0, use []const u8 instead.

Void

tape
fn do_something() -> void { }

Zero-size type for functions that return nothing.

Color literals

tape
let red: color = #FF0000;
let semi_transparent: color = #FF000080;

#RRGGBB and #RRGGBBAA syntax — produces a color value directly.

Numeric literals

tape
let decimal: i64 = 1_000_000;
let hex: u64 = 0xFF_AA_00;
let binary: u8 = 0b1010_0101;
let octal: i32 = 0o777;
let pi: f64 = 3.14159;

Underscores are allowed in numeric literals for readability.

Character values

Tape has no character literal and no character type. A character is a one-character string, converted by a builtin that says which meaning you want:

tape
if (s[i] == @byte("/")) { ... }      // 47: the one byte of a one-byte string
let nl: u8 = @byte("\n");            // escapes work as in any string
let e: u32 = @codepoint("é");        // 233: the Unicode code point
let span: i64 = @byte("z") - @byte("a");   // 25

Both are integer constants with no type of their own, like 42: they take the type the context gives them. @byte needs exactly one byte, so @byte("é") is a compile error (é is two UTF-8 bytes; you meant @codepoint), and @codepoint needs exactly one code point. Text is UTF-8 bytes, so a comparison against s[i] is a @byte; decoding code points from a string is the utf8 module’s job.

Last modified: