Language
Control flow
if and else, loops, match, and leaving a block early.
hardware {
pin led: Output = 2
}
enum Mode { idle, running, fault }
var mode: Mode = Mode.idle
setup {
var n: int = 0
while n < 3 { n += 1 }
for i in 0..10 { log("loop", "i={i}") }
for j in 0..100 step 10 { log("loop", "j={j}") }
if n > 2 {
led.on()
} else if n == 2 {
led.toggle()
} else {
led.off()
}
match(mode) {
.idle -> led.off()
.running -> led.on()
_ -> led.toggle()
}
}if and else
Conditions don’t need brackets; the block does:
hardware {
pin fan: Output = 4
pin probe: Analog = 34
}
every 1s {
let raw: int = probe.read()
if raw > 3000 {
fan.on()
} else if raw < 2500 {
fan.off()
}
}Loops
for i in a..b counts from a up to, but not including, b. step sets how far each turn goes. while repeats while its condition holds, and break and continue work as you’d expect:
setup {
var total: int = 0
for i in 0..10 {
if i == 7 { break }
if i % 2 == 0 { continue }
total += i
}
log("sum", "odd numbers below 7 add up to {total}")
}A loop that runs for a long time holds up everything else in its task. For something that should happen over time, use an
everyblock instead of a loop with waits.
match
match picks one arm by value. An arm is an enum variant (.idle), a number, a range (0..10, which leaves out 10), or _ for anything else:
hardware {
pin knob: Analog = 34
}
every 500ms {
let level: int = knob.read() / 1000
match(level) {
0 -> log("knob", "off")
1..3 -> log("knob", "low")
3 -> log("knob", "high")
_ -> log("knob", "full")
}
}An arm can be one statement or a block in { }.