pub enum Expression<'a> {
Literal(Literal),
Ident(IdentExpr<'a>),
Construct {
ty: ConstructorType<'a>,
ty_span: Span,
components: Vec<Handle<Expression<'a>>>,
},
Unary {
op: UnaryOperator,
expr: Handle<Expression<'a>>,
},
AddrOf(Handle<Expression<'a>>),
Deref(Handle<Expression<'a>>),
Binary {
op: BinaryOperator,
left: Handle<Expression<'a>>,
right: Handle<Expression<'a>>,
},
Call {
function: Ident<'a>,
arguments: Vec<Handle<Expression<'a>>>,
},
Index {
base: Handle<Expression<'a>>,
index: Handle<Expression<'a>>,
},
Member {
base: Handle<Expression<'a>>,
field: Ident<'a>,
},
Bitcast {
expr: Handle<Expression<'a>>,
to: Handle<Type<'a>>,
ty_span: Span,
},
}
Variants§
Literal(Literal)
Ident(IdentExpr<'a>)
Construct
A type constructor expression.
This is only used for expressions like KEYWORD(EXPR...)
and
KEYWORD<PARAM>(EXPR...)
, where KEYWORD
is a type-defining keyword like
vec3
. These keywords cannot be shadowed by user definitions, so we can
tell that such an expression is a construction immediately.
For ordinary identifiers, we can’t tell whether an expression like
IDENTIFIER(EXPR, ...)
is a construction expression or a function call
until we know IDENTIFIER
’s definition, so we represent those as
Call
expressions.
Unary
AddrOf(Handle<Expression<'a>>)
Deref(Handle<Expression<'a>>)
Binary
Call
A function call or type constructor expression.
We can’t tell whether an expression like IDENTIFIER(EXPR, ...)
is a
construction expression or a function call until we know IDENTIFIER
’s
definition, so we represent everything of that form as one of these
expressions until lowering. At that point, Lowerer::call
has
everything’s definition in hand, and can decide whether to emit a Naga
Constant
, As
, Splat
, or Compose
expression.