Skip to main content
Tolk supports enums, similar to TypeScript and C++ enums. In the TVM, all enums are represented as integers. At the compiler level, an enum is a distinct type.
// will be 0 1 2
enum Color {
    Red
    Green
    Blue
}

Enum members

Values can be specified manually. Otherwise, they are auto-calculated as +1.
enum Mode {
    Foo = 256,
    Bar,        // implicitly 257
}

Enum types

Enums are distinct types, not integers. Color.Red has type Color, not int, although it holds the value 0 at runtime.
fun isRed(c: Color) {
    return c == Color.Red
}

fun demo() {
    isRed(Color.Blue);    // ok
    isRed(1);             // error, pass `int` to `Color`
}
Since enums are types, they can be:
  • used as variables and parameters,
  • extended with methods,
  • used in struct fields, unions, generics, and other type contexts.
struct Gradient {
    from: Color
    to: Color? = null
}

fun Color.isRed(self) {
    return self == Color.Red
}

var g: Gradient = { from: Color.Blue };
g.from.isRed();       // false
Color.Red.isRed();    // true

match (g.to) {
    null => ...
    Color => ...
}

Exhaustive pattern matching

match on enums requires coverage of all cases:
match (someColor) {
    Color.Red => {}
    Color.Green => {}
    // error: Color.Blue is missing
}
Alternatively, use else to handle remaining values:
match (someColor) {
    Color.Red => {}
    else => {}
}
Operator == compares values directly:
if (someColor == Color.Red) {}
else {}

Integer representation

At the TVM level, every enum is represented as int. Casting between the enum and int is allowed:
  • Color.Blue as int evaluates to 2;
  • 2 as Color evaluates to Color.Blue.
Operator as can produce invalid values, for example 100 as Color. In this case, operator == returns false, and an exhaustive match throws exception 5.
During deserialization with fromCell(), the compiler validates that encoded integers correspond to valid enum values.

Usage in throw and assert

Enums are allowed in throw and assert:
enum Err {
    InvalidId = 0x100
    TooHighId
}

fun validate(id: int) {
    assert (id < 1000) throw Err.TooHighId;  // excno = 257
}

Stack layout and serialization

Every enum is backed by TVM INT and serialized as (u)intN, where N is:
  • specified manually, for example: enum Role: int8 { ... };
  • or calculated automatically to fit all values.