pub enum Pattern {
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>),
List(Vec<Pattern>, Rest),
Map(Vec<(MapKey, Pattern)>, Rest),
}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
__value <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 __value leaf, 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
__new — 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.
List(Vec<Pattern>, Rest)
[p0, …] with an optional trailing rest — a fixed-arity list pattern.
Map(Vec<(MapKey, Pattern)>, Rest)
{ k0: p0, … } — a map pattern of (key, value pattern) entries.
Rest::None is closed (exactly these keys); Rest::Anon/Named open
it (at least these keys; Named binds the remainder map).