pub enum Expr {
Show 13 variants
LetRecIn {
kw: KwLetRec,
first: RecBinding,
ands: Vec<AndBinding>,
in_kw: KwIn,
body: Box<Expr>,
},
LetIn {
kw: KwLet,
name: BindName,
ascription: Option<RecAscription>,
leading_bar: Option<BarTok>,
params: Vec<Param>,
eq: DefEqTok,
value: Box<Expr>,
in_kw: KwIn,
body: Box<Expr>,
},
LetPatternIn {
kw: KwLet,
pat: PatNonVarErased,
eq: DefEqTok,
value: Box<Expr>,
in_kw: KwIn,
body: Box<Expr>,
},
If {
kw: KwIf,
cond: Box<Expr>,
then_kw: KwThen,
then_branch: Box<Expr>,
else_kw: KwElse,
else_branch: Box<Expr>,
},
Fun {
kw: KwFun,
params: Vec<PatBot>,
arrow: ArrowTok,
body: Box<Expr>,
},
FunRows {
kw: KwFun,
opts: CstOptBinders,
param: PatBot,
arrow: ArrowTok,
body: Box<Expr>,
},
Match {
kw: KwMatch,
scrutinee: Box<Expr>,
with_kw: KwWith,
leading_bar: Option<BarTok>,
first: MatchArm,
rest: Vec<BarArm>,
},
LetMutableIn {
kw: KwLetMutable,
name: VarTok,
arrow: OverwriteEqTok,
init: Box<Expr>,
in_kw: KwIn,
body: Box<Expr>,
},
LetMathIn {
kw: KwLetMath,
cmd: HorzCmdTok,
params: Vec<Param>,
eq: DefEqTok,
value: Box<Expr>,
in_kw: KwIn,
body: Box<Expr>,
},
OpenIn {
kw: KwOpen,
name: CtorTok,
in_kw: KwIn,
body: Box<Expr>,
},
WhileDo {
kw: KwWhile,
cond: Box<Expr>,
do_kw: KwDo,
body: Box<Expr>,
},
Overwrite {
name: VarTok,
arrow: OverwriteEqTok,
value: ExprErased,
},
Ops(OpChain),
}Expand description
nxlet: a let/if/match/lambda-headed expression, falling through to
the flattened operator chain (Ops, OpChain) at the bottom.
Variant order is parse priority; Ops has no distinguishing leading
keyword, so it must stay last.
Variants§
LetRecIn
let-rec name param* = expr (and name param* = expr)* in body
LetIn
let name param* = expr in body (nxletsub’s LETNONREC case;
the bound TARGET is a plain variable — a general pattern target
is Expr::LetPatternIn, below — but param* is a full
patbot*, matching parser.mly’s nxnonrecdec (and this port’s
own TopLet/Fun/RecBinding, which already use PatBot here
too): e.g. hdecoset.satyh’s let deco _ _ _ _ = [] in ..
(Tier-2 decoration/graphics wave). Lowered by the same
elaborate::rec_clause_value single-clause path Fun’s doc
comment describes.
Fields
ascription: Option<RecAscription>Optional : ty ascription (let f : ty x = e in ..) —
parse-and-ignore, like RecBinding::ascription.
leading_bar: Option<BarTok>The | of nonrecdecargpart — see
super::TopLet::leading_bar, whose doc comment carries the
whole story; this is the expression-level twin.
LetPatternIn
let pat = value in body (nxnonrecdec’s zero-additional-
parameter case: the bound target is a general pattern, not
merely a variable name — SATySFi’s destructuring let, e.g.
let (_, acc) = pair in acc, used by the bundled
list.satyg’s mapi-adjacent). Kept as a SEPARATE variant from
Expr::LetIn above (rather than widening LetIn’s name: VarTok field to a pattern) because LetIn additionally curries
params for the ordinary let f x y = .. function-definition
shape, which upstream keys off the bound target being a plain
variable — the two shapes never overlap in real source (a
destructuring target is never itself applied to further curried
parameters). Only the no-argpart (no additional curried
parameters after the pattern) form is implemented —
nxnonrecdec’s argpart has no use in the bundled stdlib.
This variant used to be the port’s worst backtracking blow-up.
A bare-variable target like let x = 1 in x derives through here
too (PatBot::Var), and while Expr::LetIn is tried first and
always wins, this one was still tried — re-deriving value and
body in full, so a failure deep inside a let … in chain cost
×2 per enclosing let. The target is now
super::PatNonVarErased, which refuses a bare variable outright
(upstream 0.1 spells the same restriction pattern_non_var,
parser_v1.mly:796); the two alternatives are disjoint at the
token after let and the chain is linear. That type’s doc comment
carries the measurements and the proof that nothing is lost.
Must still stay after LetIn — variant order no longer
decides correctness, but it keeps the common case first.
If
if cond then a else b (nxif; else is never optional in
this grammar, so there is no dangling-else ambiguity).
Fields
Fun
fun x y -> body (nxlambda’s LAMBDA argpats ARROW nxlor
production, parser.mly:713). argpats = list(patbot)
upstream — a lambda’s parameters are full patbots, not merely
variables (e.g. the bundled list.satyg’s mapi-adjacent:
fun (i, acc) x leftopt rightopt -> .., a tuple-DESTRUCTURING
first parameter), lowered by curry_lambda_abstract_pattern —
this port’s elaborate::rec_clause_value (shared with
multi-clause let-rec, which faces the exact same
arity-preserving pattern-currying problem) reproduces that
directly, so this field is PatBot, matching RecBinding’s.
FunRows
fun ?(l = x, …) p -> body — a SATySFi 0.1 labeled-optional
lambda unit (one ?(…) bundle + one positional param). This is
an additive 0.1 node: 0.0.6 has no ?(…) param bundle, so it
is reachable in a 0.0.6 parse only for input that used to be a
parse error (a leading ? cannot begin Fun’s Vec<PatBot>),
where elaborate rejects it under a V0_0 crate::version
gate. The V0_1 pipeline reaches it by lowering a cst_v1 param
bundle (multi-unit lambdas lower to a nested FunRows/Fun
chain). Placed right after Expr::Fun so a plain fun x -> …
still matches Fun first (its ?-headed opts cannot begin a
PatBot, so Fun cleanly backtracks here for a bundled unit).
Match
match scrutinee with [|] pat [when g] -> body (| pat [when g] -> body)*
Fields
LetMutableIn
let-mutable name <- init in body (nxletsub’s LETMUTABLE
case; init/body are both nxlet in parser.mly, simplified
here to a direct Expr self-loop like LetIn).
LetMathIn
let-math \cmd param* = expr in body (nxletsub’s LETMATH
case, parser.mly:688 — upstream’s ONLY command binding with an
expression-level in form; LETHORZ/LETVERT stay
top-level-only, see the module doc comment on
super::TopBinding::LetInline/LetBlock). Same shape as
super::TopBinding::LetMath — no leading context variable,
cmd reuses the plain HorzCmdTok token — plus the in body
suffix; Box<Expr> self-loops on the recurse root like LetIn.
Fields
cmd: HorzCmdTokOpenIn
open Name in body (nxletsub’s OPEN case).
WhileDo
while cond do body (nxwhl; body is nxwhl itself in
parser.mly, i.e. right-nested whiles — simplified here to a
plain Expr).
Overwrite
name <- value (nxlambda’s OVERWRITEEQ case). Starts with a
bare VarTok, which is also how Ops can start (x alone) —
must stay before Ops so backtracking tries the <- shape
first. value is nxlor in parser.mly; routed through
ExprErased here rather than mirrored precisely, both to keep
Expr a singleton SCC and because this is already a Var-headed
alternative sitting awkwardly among the keyword-headed ones.
Ops(OpChain)
The flattened binary-operator chain — see the module doc comment on precedence flattening. Must stay last (no leading keyword).
Trait Implementations§
Source§impl<__SyanMacro_Atom> Parse<__SyanMacro_Atom> for Exprwhere
__SyanMacro_Atom: Spanned + Clone,
KwLetRec: Parse<__SyanMacro_Atom>,
RecBinding: Parse<__SyanMacro_Atom>,
Vec<AndBinding>: Parse<__SyanMacro_Atom>,
KwIn: Parse<__SyanMacro_Atom>,
KwLet: Parse<__SyanMacro_Atom>,
BindName: Parse<__SyanMacro_Atom>,
Option<RecAscription>: Parse<__SyanMacro_Atom>,
Option<BarTok>: Parse<__SyanMacro_Atom>,
Vec<Param>: Parse<__SyanMacro_Atom>,
DefEqTok: Parse<__SyanMacro_Atom>,
PatNonVarErased: Parse<__SyanMacro_Atom>,
KwIf: Parse<__SyanMacro_Atom>,
KwThen: Parse<__SyanMacro_Atom>,
KwElse: Parse<__SyanMacro_Atom>,
KwFun: Parse<__SyanMacro_Atom>,
ArrowTok: Parse<__SyanMacro_Atom>,
CstOptBinders: Parse<__SyanMacro_Atom>,
KwMatch: Parse<__SyanMacro_Atom>,
KwWith: Parse<__SyanMacro_Atom>,
MatchArm: Parse<__SyanMacro_Atom>,
Vec<BarArm>: Parse<__SyanMacro_Atom>,
KwLetMutable: Parse<__SyanMacro_Atom>,
VarTok: Parse<__SyanMacro_Atom>,
OverwriteEqTok: Parse<__SyanMacro_Atom>,
KwLetMath: Parse<__SyanMacro_Atom>,
HorzCmdTok: Parse<__SyanMacro_Atom>,
KwOpen: Parse<__SyanMacro_Atom>,
CtorTok: Parse<__SyanMacro_Atom>,
KwWhile: Parse<__SyanMacro_Atom>,
KwDo: Parse<__SyanMacro_Atom>,
ExprErased: Parse<__SyanMacro_Atom>,
OpChain: Parse<__SyanMacro_Atom>,
Box<PatternParenBody>: Parse<__SyanMacro_Atom>,
Vec<PatListItem>: Parse<__SyanMacro_Atom>,
IntTok: Parse<__SyanMacro_Atom>,
KwTrue: Parse<__SyanMacro_Atom>,
KwFalse: Parse<__SyanMacro_Atom>,
LiteralTok: Parse<__SyanMacro_Atom>,
WildcardTok: Parse<__SyanMacro_Atom>,
UnitParen: Parse<__SyanMacro_Atom>,
ParenGroup<()>: GroupShape<__SyanMacro_Atom>,
ListGroup<()>: GroupShape<__SyanMacro_Atom>,
Self: ParseRanked8909385c15d27adc<(((),),), __SyanMacro_Atom>,
impl<__SyanMacro_Atom> Parse<__SyanMacro_Atom> for Exprwhere
__SyanMacro_Atom: Spanned + Clone,
KwLetRec: Parse<__SyanMacro_Atom>,
RecBinding: Parse<__SyanMacro_Atom>,
Vec<AndBinding>: Parse<__SyanMacro_Atom>,
KwIn: Parse<__SyanMacro_Atom>,
KwLet: Parse<__SyanMacro_Atom>,
BindName: Parse<__SyanMacro_Atom>,
Option<RecAscription>: Parse<__SyanMacro_Atom>,
Option<BarTok>: Parse<__SyanMacro_Atom>,
Vec<Param>: Parse<__SyanMacro_Atom>,
DefEqTok: Parse<__SyanMacro_Atom>,
PatNonVarErased: Parse<__SyanMacro_Atom>,
KwIf: Parse<__SyanMacro_Atom>,
KwThen: Parse<__SyanMacro_Atom>,
KwElse: Parse<__SyanMacro_Atom>,
KwFun: Parse<__SyanMacro_Atom>,
ArrowTok: Parse<__SyanMacro_Atom>,
CstOptBinders: Parse<__SyanMacro_Atom>,
KwMatch: Parse<__SyanMacro_Atom>,
KwWith: Parse<__SyanMacro_Atom>,
MatchArm: Parse<__SyanMacro_Atom>,
Vec<BarArm>: Parse<__SyanMacro_Atom>,
KwLetMutable: Parse<__SyanMacro_Atom>,
VarTok: Parse<__SyanMacro_Atom>,
OverwriteEqTok: Parse<__SyanMacro_Atom>,
KwLetMath: Parse<__SyanMacro_Atom>,
HorzCmdTok: Parse<__SyanMacro_Atom>,
KwOpen: Parse<__SyanMacro_Atom>,
CtorTok: Parse<__SyanMacro_Atom>,
KwWhile: Parse<__SyanMacro_Atom>,
KwDo: Parse<__SyanMacro_Atom>,
ExprErased: Parse<__SyanMacro_Atom>,
OpChain: Parse<__SyanMacro_Atom>,
Box<PatternParenBody>: Parse<__SyanMacro_Atom>,
Vec<PatListItem>: Parse<__SyanMacro_Atom>,
IntTok: Parse<__SyanMacro_Atom>,
KwTrue: Parse<__SyanMacro_Atom>,
KwFalse: Parse<__SyanMacro_Atom>,
LiteralTok: Parse<__SyanMacro_Atom>,
WildcardTok: Parse<__SyanMacro_Atom>,
UnitParen: Parse<__SyanMacro_Atom>,
ParenGroup<()>: GroupShape<__SyanMacro_Atom>,
ListGroup<()>: GroupShape<__SyanMacro_Atom>,
Self: ParseRanked8909385c15d27adc<(((),),), __SyanMacro_Atom>,
Source§type Error = <Expr as ParseRanked8909385c15d27adc<(((),),), __SyanMacro_Atom>>::Error
type Error = <Expr as ParseRanked8909385c15d27adc<(((),),), __SyanMacro_Atom>>::Error
<FieldTy as Parse<Atom>>::Error: Into<…> predicate re-creates a projection cycle on a
recursive field (E0275), which decycle’s bound-peeling does not break.