pub enum Ast<I = String> {
Show 34 variants
Unit,
Bool(bool),
Int(i64),
Float(f64),
Length(Length),
Str(String),
Var(I, Span),
Apply(Box<Ast<I>>, Box<Ast<I>>),
Lambda(I, Rc<Ast<I>>),
LetIn(I, Box<Ast<I>>, Box<Ast<I>>),
LetRecIn(Vec<(I, Rc<Ast<I>>)>, Box<Ast<I>>),
LetMathIn(I, Box<Ast<I>>, Box<Ast<I>>),
IfThenElse(Box<Ast<I>>, Box<Ast<I>>, Box<Ast<I>>),
Match(Box<Ast<I>>, Vec<MatchArm<I>>),
Tuple(Vec<Ast<I>>),
Ctor(String, Option<Box<Ast<I>>>),
Record(Vec<(String, Ast<I>)>),
List(Vec<Ast<I>>),
InlineText(Rc<Vec<IText<I>>>),
BlockText(Rc<Vec<BText<I>>>),
MathText(Rc<Vec<MathElem<I>>>),
LetMutableIn(I, Box<Ast<I>>, Box<Ast<I>>),
Overwrite(I, Span, Box<Ast<I>>),
WhileDo(Box<Ast<I>>, Box<Ast<I>>),
Sequential(Box<Ast<I>>, Box<Ast<I>>),
AccessField(Box<Ast<I>>, String, Span),
UpdateField(Box<Ast<I>>, String, Box<Ast<I>>),
ApplyOpt {
func: Box<Ast<I>>,
opts: Vec<(String, Ast<I>)>,
arg: Box<Ast<I>>,
},
LambdaOpt {
opts: Vec<(String, I)>,
param: I,
body: Rc<Ast<I>>,
},
VersionScope(RustyfiVersion, Box<Ast<I>>),
ModuleScope(Vec<String>, Box<Ast<I>>),
StageScope(Stage, Box<Ast<I>>),
Next(Box<Ast<I>>),
Prev(Box<Ast<I>>),
}Variants§
Unit
Bool(bool)
Int(i64)
Float(f64)
Length(Length)
Str(String)
Var(I, Span)
Apply(Box<Ast<I>>, Box<Ast<I>>)
Lambda(I, Rc<Ast<I>>)
LetIn(I, Box<Ast<I>>, Box<Ast<I>>)
LetRecIn(Vec<(I, Rc<Ast<I>>)>, Box<Ast<I>>)
Mutually recursive bindings (let-rec … and …); every body must be a
Lambda, all names are in scope in all bodies.
LetMathIn(I, Box<Ast<I>>, Box<Ast<I>>)
let-math \cmd param* = expr in body — a math-command binding.
Evaluates identically to LetIn; the DISTINCT variant exists purely
so the typechecker can tell it apart from an ordinary \-sigiled
LetIn (a let-inline binding, or a qualified-name alias of one)
without re-deriving that from the shared \ sigil — see
typecheck.rs’s Checker::math_command_scheme.
IfThenElse(Box<Ast<I>>, Box<Ast<I>>, Box<Ast<I>>)
Match(Box<Ast<I>>, Vec<MatchArm<I>>)
Tuple(Vec<Ast<I>>)
Ctor(String, Option<Box<Ast<I>>>)
A variant constructor, optionally applied (None / Some 3).
The tag is a data-level name, not an environment key — see the module
doc comment on what I does and does not cover.
Record(Vec<(String, Ast<I>)>)
List(Vec<Ast<I>>)
InlineText(Rc<Vec<IText<I>>>)
Quoted inline text: evaluated only when read-inline runs it.
BlockText(Rc<Vec<BText<I>>>)
Quoted block text: evaluated only when read-block runs it.
MathText(Rc<Vec<MathElem<I>>>)
Quoted math text (${…}); typesetting is deferred, the
value is carried opaquely until then.
LetMutableIn(I, Box<Ast<I>>, Box<Ast<I>>)
let-mutable x <- init in body — binds x to a mutable cell.
Overwrite(I, Span, Box<Ast<I>>)
x <- e — overwrite a mutable cell; evaluates to unit.
WhileDo(Box<Ast<I>>, Box<Ast<I>>)
while cond do body — evaluates to unit.
Sequential(Box<Ast<I>>, Box<Ast<I>>)
e1 before e2 (UTSequential) — evaluate e1 for effect, then e2.
AccessField(Box<Ast<I>>, String, Span)
e#label (UTAccessField). The label is a record field, not an
environment key — see the module doc comment.
UpdateField(Box<Ast<I>>, String, Box<Ast<I>>)
(| e with label = v |) (UTUpdateField) — functional record update.
ApplyOpt
f ?(l = e, …) arg — SATySFi 0.1 labeled-optional application
(upstream Apply(labmap, e1, e2)). opts is non-empty by
construction: a bundle-less 0.1 application lowers to plain
Ast::Apply. Labels are deduplicated at elaboration; at
beta-reduction a provided ?(l = e) binds the closure’s l binder to
Some e, and any declared label the call omits binds None (see
eval::Interp::apply_with_opts).
LambdaOpt
fun ?(l = x, …) p -> body — SATySFi 0.1 labeled-optional lambda
(upstream Function(evid_labmap, patbr)). opts maps each label to
the binder name that receives its option-typed value. Pattern
params are pre-desugared (by elaborate) to a fresh var + Match,
like rec_clause_value, so param here is always a plain binder.
Note the mixed pair: each label is data (String — it is matched
against a call site’s ?(l = e) labels), while each binder is a
lexical variable (I — it becomes an environment key).
VersionScope(RustyfiVersion, Box<Ast<I>>)
A version tag around one spliced cross-version dependency binding’s
RHS. elaborate.rs’s cross-version splice
wraps each binding contributed by a LoadedCst::V0_0 dependency in
VersionScope(V0_0, rhs), at RHS granularity (never the surrounding
LetIn/LetRecIn node, and never the continuation that follows it).
Three consumers push/pop a cursor around recursing into body:
compile.rs’sCompiler::current_version— which base environment (V0_1’s orV0_0’s) an unshadowedAst::Varconstant-folds against, so a version-forked primitive (page-break,math-*, …) freezes to the RIGHT version’sPrimDefat compile time (the only version-sensitive resolution in the whole pipeline).eval.rs’sInterp::version— any runtime fork that reads it (primitives.rs’sreflect_math_elem/coerce_graphics_result/make_paren_run) seesV0_0while evaluating on behalf of this subtree.typecheck.rs’s base-type-env swap — the subtree’s internal forked-primitive-type use checks againstV0_0’s primitive types.
Never emitted on a pure single-version load — structurally inert on the pure-0.0.6/pure-0.1 paths: no arm executes, no runtime check is involved.
ModuleScope(Vec<String>, Box<Ast<I>>)
ModuleScope(["M", "N"], rhs): marks that rhs is the body of a
member of module M.N, so a BARE constructor reference inside it
resolves against that module’s constructors first (the type/ctor
analog of push_named_binding’s value Scope::rename). Transparent
everywhere except Checker::infer/bind_pattern, which push the
path and try qualified ctor keys before the bare fallback — no
constructor NAME string ever changes (eval, exhaustiveness, and
error/warning text stay byte-identical). Wraps a module member’s RHS
only, exactly like VersionScope.
StageScope(Stage, Box<Ast<I>>)
Marks body as coming from a file that declared a stage other than
the default (@stage: 0 / @stage: persistent), so the typechecker
reads it at that stage and its & quotes are legal there.
The stage analogue of Ast::VersionScope, and for the same reason:
the loader concatenates every library’s prelude into ONE file, so a
per-file property has to travel with the bindings it came from or be
lost at the merge.
Next(Box<Ast<I>>)
&e — quote. Evaluated at stage 0, it does NOT run e: it partially
evaluates it into residual code and yields that code as a value
(Value::Code), typed code ty. Upstream’s UTNext/Next
(parser.mly:796, evaluator.cppo.ml’s interpret_1).
Prev(Box<Ast<I>>)
~e — splice. Legal inside a quote (stage 1): e is evaluated NOW,
at stage 0, and the code it yields is spliced in where the ~e stood.
Upstream’s UTPrev/Prev (parser.mly:797).
Implementations§
Trait Implementations§
impl<I: PartialEq> StructuralPartialEq for Ast<I>
Auto Trait Implementations§
impl<I = String> !Send for Ast<I>
impl<I = String> !Sync for Ast<I>
impl<I> Freeze for Ast<I>where
I: Freeze,
Box<Ast<I>>: Freeze,
Rc<Ast<I>>: Freeze,
Vec<(I, Rc<Ast<I>>)>: Freeze,
Vec<MatchArm<I>>: Freeze,
Vec<Ast<I>>: Freeze,
Option<Box<Ast<I>>>: Freeze,
Vec<(String, Ast<I>)>: Freeze,
Rc<Vec<IText<I>>>: Freeze,
Rc<Vec<BText<I>>>: Freeze,
Rc<Vec<MathElem<I>>>: Freeze,
Vec<(String, I)>: Freeze,
impl<I> RefUnwindSafe for Ast<I>where
I: RefUnwindSafe,
Box<Ast<I>>: RefUnwindSafe,
Rc<Ast<I>>: RefUnwindSafe,
Vec<(I, Rc<Ast<I>>)>: RefUnwindSafe,
Vec<MatchArm<I>>: RefUnwindSafe,
Vec<Ast<I>>: RefUnwindSafe,
Option<Box<Ast<I>>>: RefUnwindSafe,
Vec<(String, Ast<I>)>: RefUnwindSafe,
Rc<Vec<IText<I>>>: RefUnwindSafe,
Rc<Vec<BText<I>>>: RefUnwindSafe,
Rc<Vec<MathElem<I>>>: RefUnwindSafe,
Vec<(String, I)>: RefUnwindSafe,
impl<I> Unpin for Ast<I>
impl<I> UnsafeUnpin for Ast<I>where
I: UnsafeUnpin,
Box<Ast<I>>: UnsafeUnpin,
Rc<Ast<I>>: UnsafeUnpin,
Vec<(I, Rc<Ast<I>>)>: UnsafeUnpin,
Vec<MatchArm<I>>: UnsafeUnpin,
Vec<Ast<I>>: UnsafeUnpin,
Option<Box<Ast<I>>>: UnsafeUnpin,
Vec<(String, Ast<I>)>: UnsafeUnpin,
Rc<Vec<IText<I>>>: UnsafeUnpin,
Rc<Vec<BText<I>>>: UnsafeUnpin,
Rc<Vec<MathElem<I>>>: UnsafeUnpin,
Vec<(String, I)>: UnsafeUnpin,
impl<I> UnwindSafe for Ast<I>where
I: UnwindSafe,
Box<Ast<I>>: UnwindSafe,
Rc<Ast<I>>: UnwindSafe,
Vec<(I, Rc<Ast<I>>)>: UnwindSafe,
Vec<MatchArm<I>>: UnwindSafe,
Vec<Ast<I>>: UnwindSafe,
Option<Box<Ast<I>>>: UnwindSafe,
Vec<(String, Ast<I>)>: UnwindSafe,
Rc<Vec<IText<I>>>: UnwindSafe,
Rc<Vec<BText<I>>>: UnwindSafe,
Rc<Vec<MathElem<I>>>: UnwindSafe,
Vec<(String, I)>: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more