examples/gallery/02-tokens.hero
Define a value with several possible forms and handle every case.
- 53 lines
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
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))
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.