Heroes / Examples / 02-tokens

examples/gallery/02-tokens.hero

Define a value with several possible forms and handle every case.

A variant is a type with several named cases. A match must handle every case explicitly; a catch-all branch is not allowed. If you add a case, the compiler points out every match that needs updating.

Run it

$ heroes run examples/gallery/02-tokens.hero

These files introduce the language one feature at a time. This page shows the program and not a result, because no test compares their output byte for byte yet.

The program

## Tokens
#
# A variant with payloads, and the only construct that takes one apart.
# `match` is exhaustive or the program does not compile, and `_` is
# forbidden on a variant — adding a case has to break something.

variant Token
    number
        value: i64
    word
        text: str
    plus
    times
    open
    close

# What a token is called in a message.
function name_of(t: Token) -> str
    return match t
        .number _ => "a number"
        .word _   => "a word"
        .plus     => "`+`"
        .times    => "`*`"
        .open     => "`(`"
        .close    => "`)`"

# Binding power, strongest first (§4.14's table, in miniature).
function power_of(t: Token) -> i64
    return match t
        .times         => 2
        .plus          => 1
        .number _      => 0
        .word _        => 0
        .open | .close => 0

function is_operator(t: Token) -> bool
    return match t
        .plus | .times                       => true
        .number _ | .word _ | .open | .close => false

test "every token has a name and a power"
    assert name_of(.plus) == "`+`"
    assert power_of(.times) > power_of(.plus)
    assert is_operator(.number(value: 7)) == false

function main()
    # The annotation is required and it is not ceremony: a case says which
    # case it is, never which variant, so a literal list of them has nothing
    # to infer from. Name the type once and the whole list is checked.
    line: [Token] = [.open, .number(value: 12), .plus, .word(text: "x"), .close]

    for t in line
        print(name_of(t))
examples/gallery/02-tokens.hero, 53 lines

fingerprint sha256 2862b0a6f461 · 1 file · index.json

Next: 03-fallible. All the examples. ← Previous: 01-points

Run one yourself: the four commands. Learn the language, or read the full specification in one file.