pub enum ExprKind<P: Phase = Raw> {
Show 23 variants
Number(f64),
Integer(i64),
Bool(bool),
StringLiteral(String),
GraphRef(Spanned<ScopedName>),
BinOp {
op: BinOp,
lhs: Box<Expr<P>>,
rhs: Box<Expr<P>>,
},
UnaryOp {
op: UnaryOp,
operand: Box<Expr<P>>,
},
FnCall {
callee: IdentPath,
type_args: Vec<GenericArg<P>>,
args: Vec<Expr<P>>,
},
If {
condition: Box<Expr<P>>,
then_branch: Box<Expr<P>>,
else_branch: Box<Expr<P>>,
},
UnitLiteral {
value: f64,
unit: UnitExpr,
},
Convert {
expr: Box<Expr<P>>,
target: UnitExpr,
},
DisplayTimezone {
expr: Box<Expr<P>>,
timezone: String,
},
FieldAccess {
expr: Box<Expr<P>>,
field: Spanned<FieldName>,
},
ConstructorCall {
callee: IdentPath,
generic_args: Vec<GenericArg<P>>,
fields: Vec<FieldInit<P>>,
},
MapLiteral {
entries: Vec<MapEntry<P>>,
},
ForComp {
bindings: Vec<ForBinding>,
body: Box<Expr<P>>,
},
IndexAccess {
expr: Box<Expr<P>>,
args: Vec<IndexArg<P>>,
},
Scan {
source: Box<Expr<P>>,
init: Box<Expr<P>>,
acc_name: Spanned<LocalName>,
val_name: Spanned<LocalName>,
body: Box<Expr<P>>,
},
Unfold {
init: Box<Expr<P>>,
prev_name: Spanned<LocalName>,
curr_name: Spanned<LocalName>,
body: Box<Expr<P>>,
},
Match {
scrutinee: Box<Expr<P>>,
arms: Vec<MatchArm<P>>,
},
InlineDagRef {
path: ModulePath,
args: Vec<ParamBinding<P>>,
output: Spanned<DeclName>,
},
UnresolvedRef(UnresolvedRef),
Sugar(P::ExprSugar),
}Variants§
Number(f64)
Numeric literal: 1200.0, 3.98e5, 200_000.0
Integer(i64)
Integer literal: 42, 1_000
Bool(bool)
Boolean literal: true, false
StringLiteral(String)
String literal: "hello" (used as arguments to datetime(), epoch(), etc.)
GraphRef(Spanned<ScopedName>)
Graph reference: @name or @alias.member. The payload encodes
qualification structurally — Local for bare @name, Qualified
for @alias.member (after the namespace-alias rewrite). Producers
never invent or interpret a flat-string separator.
BinOp
Binary operation: a + b, a * b, a ^ b, a && b, etc.
UnaryOp
Unary operation: -x, !x
FnCall
Function call syntax: sqrt(x), atan2(y, x), eye<3>(), or module.fn(x).
The callee is a syntactic path. Bare calls and qualified calls have the same AST shape; semantic categorization/resolution happens later.
If
Conditional: if cond { then_expr } else { else_expr }
UnitLiteral
Unit-annotated literal: 400 km, 9.80665 m/s^2
Convert
Conversion: expr -> unit_expr
DisplayTimezone
Timezone display: expr -> "America/New_York" (datetime only)
FieldAccess
Field access: @transfer.dv1, @mission.transfer.dv1
ConstructorCall
Constructor-call syntax for values of user-defined unified type declarations.
Payload constructors use named arguments, e.g.
TransferResult(dv1: @dv1, dv2: @dv2) or
module.TransferResult(dv1: @dv1). The callee is a syntactic path; name
resolution decides whether it denotes a constructor.
MapLiteral
Map literal: { Maneuver.Departure: 2.46 km/s, Maneuver.Correction: 0.05 km/s }
ForComp
For comprehension: for m: Maneuver { @delta_v[m] + 1.0 }
IndexAccess
Index access: @delta_v[m], @delta_v[Maneuver.Departure], @P[a, b]
Scan
Scan: scan(source, init, |acc, val| body)
Fields
Unfold
Unfold: unfold(init, |prev_i, i| body)
Generates an indexed value from a seed by iterating over a range index.
The closure receives (prev_i, i) bindings for the previous and current
step indices, and the body can reference @node_name[prev_i].
Fields
Match
Match expression: match @status { Nominal => ..., Warning(message: code) => ... }
InlineDagRef
Inline DAG invocation: @dag(args).out or @module.dag(args).out.
Each syntactic occurrence denotes a fresh DAG instantiation that is
desugared during TIR lowering to the equivalent
include <path>(args) as <synthetic>; @<synthetic>.out. Preserved as
a distinct AST variant so source spans survive for diagnostics.
The post-@ expression as a whole must denote a node — that is the
invariant @ enforces. @dag(args).out is well-formed because
dag(args).out projects an output node from a fresh DAG instance, and
likewise @module.dag(args).out projects an output node from a DAG
brought into scope via import module.{dag}; or import path as module;. Bare @dag(args) (no projection) is rejected — a DAG
instance with no projection is not a node.
Fields
path: ModulePathPath to the DAG being invoked. Single-segment for same-file calls
(@dag(args).out), multi-segment for cross-file qualified calls
(@module.dag(args).out). The leaf segment names the DAG; any
preceding segments resolve through module aliases brought into
scope by import.
args: Vec<ParamBinding<P>>Param/index bindings, same shape as include bindings.
UnresolvedRef(UnresolvedRef)
Unresolved reference produced by the parser.
Carries an unresolved identifier path. HIR expression lowering is the single stage that classifies and resolves these paths.
Sugar(P::ExprSugar)
Phase-specific expression sugar.
In Raw, this is crate::syntax::ast::RawExprSugar and carries
surface forms like TableLiteral that are eliminated by the desugar
pass. In Desugared, the payload is core::convert::Infallible —
the variant is statically unreachable.
Trait Implementations§
Source§impl FormatEquivalent for ExprKind
impl FormatEquivalent for ExprKind
Source§fn format_equivalent(&self, other: &Self) -> bool
fn format_equivalent(&self, other: &Self) -> bool
true if self and other are equivalent up to formatting.