pub enum Pattern {
Show 13 variants
Discard,
Bind(Text),
At(Text, Box<Pattern>),
Equal(Expr),
Less(Expr),
Greater(Expr),
Type(ProtoRef, Box<Pattern>),
Unwrap {
depth: u32,
inner: Box<Pattern>,
},
Or(Box<Pattern>, Box<Pattern>),
Unit,
List {
elems: Vec<Pattern>,
rest: Option<Box<Pattern>>,
},
Map {
entries: Vec<(MapKey, Pattern)>,
rest: Option<Box<Pattern>>,
},
When {
inner: Box<Pattern>,
when: (Option<Box<Pattern>>, Expr),
},
}Expand description
A pattern: the left-hand side of any binding (&<pat> …, let (<pat> = …), a __match clause). Matched against a value by the evaluator’s native
matcher (match_pattern in eval.rs), which either extends the environment
or refutes. Bind/Discard are irrefutable; every other shape may refute.
Variants§
Discard
_ — matches anything, binds nothing.
Bind(Text)
name — binds the subject to name. The matcher conses one cell carrying
the subject onto the environment; the name itself is not stored at runtime
(references to it were resolved to a de Bruijn index).
At(Text, Box<Pattern>)
name = <pat> — binds the subject to name, then matches <pat> against
the same subject.
Equal(Expr)
= <expr> (and its .sym sugar) — matches iff the subject equals the
value of <expr>; binds nothing. Evaluating <expr> may raise a real
error, which propagates (it is not a refutation).
Less(Expr)
< <expr> — matches iff the subject is (strictly) ordered before the value
of <expr>; binds nothing. Ordering is defined only within a comparable
kind (Int for now, later Str), so a subject/bound that are not both of
one such kind refute with .not_int (a refutation, not a host raise).
Greater(Expr)
> <expr> — the mirror of Less: matches iff the subject
is ordered after the value of <expr>.
Type(ProtoRef, Box<Pattern>)
<pat> as <Proto> / (as <Proto>) <pat> — matches iff the subject’s
prototype is <Proto>, then matches <pat> against the (narrowed)
subject. See ProtoRef for the two forms the prototype takes.
Unwrap
Self <pat> — matches iff the subject is an object of the home
module and its payload matches <pat>, binding what the inner pattern
binds. It is the pattern side of the payload read,
and the prototype check is implicit for the same reason the leaf’s is:
unwrapping a foreign object has no sound reading.
It holds no reference — the module is implicit, exactly as it is for
#Self — so the pattern grammar stays closed. depth is the leaf’s, and
the matcher walks the environment to that terminal and compares the
prototype by pointer before descending.
Or(Box<Pattern>, Box<Pattern>)
(p1 | p2) — try the left arm, on refutation try the right. Both arms bind
the same set of names (checked at parse time). Committed: once an arm’s
pattern matches, a later failure does not backtrack into the other arm.
Unit
&() — matches the unit value and nothing else, binding
nothing. Distinct from the empty list pattern &[] / &#[], which
matches the empty list.
List
[p0, ...] list pattern. rest matches the remainder of the list:
None for exact arity, Some(Discard) (...) for minimum arity,
and Some(Bind(name)) (...name) to bind the remainder.
Map
{ k0: p0, ... } map pattern. rest matches the remainder map as in Pattern::List.
When
<pat> when (<cond>) guarded pattern. Matches inner, then the guard.
Plain guards (None) must be Bool and refute on __false.
Pattern guards (Some(gpat)) match gpat against the condition’s value.
Guards can nest and their bindings are visible to the body.