language::machinesA machine declares a closed set of events, states, and transition rules.
step mutates a machine value, and state_name returns its current state.
Every state/event cell must be covered. default { state } is the explicit
no-op stay rule for all cells not otherwise listed.
machine Counter {
events { Inc; Reset; }
state Zero;
state NonZero { value: i64; }
on Inc: Zero => NonZero { value: 1 }
on Inc: NonZero => NonZero reenter { value: state.value + 1 }
on Reset: NonZero => Zero;
default { state }
}
fn main() {
var counter: Counter = .Zero;
let _ = counter.step(.Inc);
let _ = counter.step(.Inc);
println(counter.state_name());
}
A rule head names the state the transition produces, so the body carries
only what the head cannot: nothing for a unit target, the field list for a
fielded one, and an expression when the value is computed. state.field
reads the source state and event.field reads the event payload; self is
an actor or method receiver and is not bound here.
reenter marks a self-state transition that re-enters the state's
lifecycle rather than being treated as an ordinary stay. It is useful when
a self-transition must rebuild state or trigger state-entry behaviour.
Wildcards are asymmetric: _ is allowed for a state pattern, but events
must be named explicitly. For example, on Kill: _ => Dead, covers Kill
from every state, but there is no wildcard-event spelling. Explicit cells
win over wildcard-state rules. Omitting a cell without a matching default
is a compile error, so state and event exhaustiveness is enforced rather
than inferred at runtime.