1use alloc::vec::Vec;
2use core::hash::Hash;
3
4use crate::diagnostic_filter::DiagnosticFilterNode;
5use crate::front::wgsl::parse::directive::enable_extension::EnableExtensions;
6use crate::front::wgsl::parse::number::Number;
7use crate::front::wgsl::Scalar;
8use crate::{Arena, FastIndexSet, Handle, Span};
9
10#[derive(Debug, Default)]
11pub struct TranslationUnit<'a> {
12 pub enable_extensions: EnableExtensions,
13 pub decls: Arena<GlobalDecl<'a>>,
14 pub expressions: Arena<Expression<'a>>,
26
27 pub types: Arena<Type<'a>>,
32
33 pub diagnostic_filters: Arena<DiagnosticFilterNode>,
38 pub diagnostic_filter_leaf: Option<Handle<DiagnosticFilterNode>>,
43}
44
45#[derive(Debug, Clone, Copy)]
46pub struct Ident<'a> {
47 pub name: &'a str,
48 pub span: Span,
49}
50
51#[derive(Debug)]
52pub enum IdentExpr<'a> {
53 Unresolved(&'a str),
54 Local(Handle<Local>),
55}
56
57#[derive(Debug)]
64pub struct Dependency<'a> {
65 pub ident: &'a str,
67
68 pub usage: Span,
70}
71
72impl Hash for Dependency<'_> {
73 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
74 self.ident.hash(state);
75 }
76}
77
78impl PartialEq for Dependency<'_> {
79 fn eq(&self, other: &Self) -> bool {
80 self.ident == other.ident
81 }
82}
83
84impl Eq for Dependency<'_> {}
85
86#[derive(Debug)]
88pub struct GlobalDecl<'a> {
89 pub kind: GlobalDeclKind<'a>,
90
91 pub dependencies: FastIndexSet<Dependency<'a>>,
94}
95
96#[derive(Debug)]
97pub enum GlobalDeclKind<'a> {
98 Fn(Function<'a>),
99 Var(GlobalVariable<'a>),
100 Const(Const<'a>),
101 Override(Override<'a>),
102 Struct(Struct<'a>),
103 Type(TypeAlias<'a>),
104 ConstAssert(Handle<Expression<'a>>),
105}
106
107#[derive(Debug)]
108pub struct FunctionArgument<'a> {
109 pub name: Ident<'a>,
110 pub ty: Handle<Type<'a>>,
111 pub binding: Option<Binding<'a>>,
112 pub handle: Handle<Local>,
113}
114
115#[derive(Debug)]
116pub struct FunctionResult<'a> {
117 pub ty: Handle<Type<'a>>,
118 pub binding: Option<Binding<'a>>,
119 pub must_use: bool,
120}
121
122#[derive(Debug)]
123pub struct EntryPoint<'a> {
124 pub stage: crate::ShaderStage,
125 pub early_depth_test: Option<crate::EarlyDepthTest>,
126 pub workgroup_size: Option<[Option<Handle<Expression<'a>>>; 3]>,
127}
128
129#[cfg(doc)]
130use crate::front::wgsl::lower::{LocalExpressionContext, StatementContext};
131
132#[derive(Debug)]
133pub struct Function<'a> {
134 pub entry_point: Option<EntryPoint<'a>>,
135 pub name: Ident<'a>,
136 pub arguments: Vec<FunctionArgument<'a>>,
137 pub result: Option<FunctionResult<'a>>,
138 pub body: Block<'a>,
139 pub diagnostic_filter_leaf: Option<Handle<DiagnosticFilterNode>>,
140}
141
142#[derive(Debug)]
143pub enum Binding<'a> {
144 BuiltIn(crate::BuiltIn),
145 Location {
146 location: Handle<Expression<'a>>,
147 interpolation: Option<crate::Interpolation>,
148 sampling: Option<crate::Sampling>,
149 blend_src: Option<Handle<Expression<'a>>>,
150 },
151}
152
153#[derive(Debug)]
154pub struct ResourceBinding<'a> {
155 pub group: Handle<Expression<'a>>,
156 pub binding: Handle<Expression<'a>>,
157}
158
159#[derive(Debug)]
160pub struct GlobalVariable<'a> {
161 pub name: Ident<'a>,
162 pub space: crate::AddressSpace,
163 pub binding: Option<ResourceBinding<'a>>,
164 pub ty: Option<Handle<Type<'a>>>,
165 pub init: Option<Handle<Expression<'a>>>,
166}
167
168#[derive(Debug)]
169pub struct StructMember<'a> {
170 pub name: Ident<'a>,
171 pub ty: Handle<Type<'a>>,
172 pub binding: Option<Binding<'a>>,
173 pub align: Option<Handle<Expression<'a>>>,
174 pub size: Option<Handle<Expression<'a>>>,
175}
176
177#[derive(Debug)]
178pub struct Struct<'a> {
179 pub name: Ident<'a>,
180 pub members: Vec<StructMember<'a>>,
181}
182
183#[derive(Debug)]
184pub struct TypeAlias<'a> {
185 pub name: Ident<'a>,
186 pub ty: Handle<Type<'a>>,
187}
188
189#[derive(Debug)]
190pub struct Const<'a> {
191 pub name: Ident<'a>,
192 pub ty: Option<Handle<Type<'a>>>,
193 pub init: Handle<Expression<'a>>,
194}
195
196#[derive(Debug)]
197pub struct Override<'a> {
198 pub name: Ident<'a>,
199 pub id: Option<Handle<Expression<'a>>>,
200 pub ty: Option<Handle<Type<'a>>>,
201 pub init: Option<Handle<Expression<'a>>>,
202}
203
204#[derive(Debug, Copy, Clone)]
209pub enum ArraySize<'a> {
210 Constant(Handle<Expression<'a>>),
212 Dynamic,
213}
214
215#[derive(Debug)]
216pub enum Type<'a> {
217 Scalar(Scalar),
218 Vector {
219 size: crate::VectorSize,
220 ty: Handle<Type<'a>>,
221 ty_span: Span,
222 },
223 Matrix {
224 columns: crate::VectorSize,
225 rows: crate::VectorSize,
226 ty: Handle<Type<'a>>,
227 ty_span: Span,
228 },
229 Atomic(Scalar),
230 Pointer {
231 base: Handle<Type<'a>>,
232 space: crate::AddressSpace,
233 },
234 Array {
235 base: Handle<Type<'a>>,
236 size: ArraySize<'a>,
237 },
238 Image {
239 dim: crate::ImageDimension,
240 arrayed: bool,
241 class: crate::ImageClass,
242 },
243 Sampler {
244 comparison: bool,
245 },
246 AccelerationStructure {
247 vertex_return: bool,
248 },
249 RayQuery {
250 vertex_return: bool,
251 },
252 RayDesc,
253 RayIntersection,
254 BindingArray {
255 base: Handle<Type<'a>>,
256 size: ArraySize<'a>,
257 },
258
259 User(Ident<'a>),
261}
262
263#[derive(Debug, Default)]
264pub struct Block<'a> {
265 pub stmts: Vec<Statement<'a>>,
266}
267
268#[derive(Debug)]
269pub struct Statement<'a> {
270 pub kind: StatementKind<'a>,
271 pub span: Span,
272}
273
274#[derive(Debug)]
275pub enum StatementKind<'a> {
276 LocalDecl(LocalDecl<'a>),
277 Block(Block<'a>),
278 If {
279 condition: Handle<Expression<'a>>,
280 accept: Block<'a>,
281 reject: Block<'a>,
282 },
283 Switch {
284 selector: Handle<Expression<'a>>,
285 cases: Vec<SwitchCase<'a>>,
286 },
287 Loop {
288 body: Block<'a>,
289 continuing: Block<'a>,
290 break_if: Option<Handle<Expression<'a>>>,
291 },
292 Break,
293 Continue,
294 Return {
295 value: Option<Handle<Expression<'a>>>,
296 },
297 Kill,
298 Call {
299 function: Ident<'a>,
300 arguments: Vec<Handle<Expression<'a>>>,
301 },
302 Assign {
303 target: Handle<Expression<'a>>,
304 op: Option<crate::BinaryOperator>,
305 value: Handle<Expression<'a>>,
306 },
307 Increment(Handle<Expression<'a>>),
308 Decrement(Handle<Expression<'a>>),
309 Phony(Handle<Expression<'a>>),
310 ConstAssert(Handle<Expression<'a>>),
311}
312
313#[derive(Debug)]
314pub enum SwitchValue<'a> {
315 Expr(Handle<Expression<'a>>),
316 Default,
317}
318
319#[derive(Debug)]
320pub struct SwitchCase<'a> {
321 pub value: SwitchValue<'a>,
322 pub body: Block<'a>,
323 pub fall_through: bool,
324}
325
326#[derive(Debug)]
347pub enum ConstructorType<'a> {
348 Scalar(Scalar),
350
351 PartialVector { size: crate::VectorSize },
354
355 Vector {
358 size: crate::VectorSize,
359 ty: Handle<Type<'a>>,
360 ty_span: Span,
361 },
362
363 PartialMatrix {
366 columns: crate::VectorSize,
367 rows: crate::VectorSize,
368 },
369
370 Matrix {
373 columns: crate::VectorSize,
374 rows: crate::VectorSize,
375 ty: Handle<Type<'a>>,
376 ty_span: Span,
377 },
378
379 PartialArray,
382
383 Array {
386 base: Handle<Type<'a>>,
387 size: ArraySize<'a>,
388 },
389
390 Type(Handle<crate::Type>),
395}
396
397#[derive(Debug, Copy, Clone)]
398pub enum Literal {
399 Bool(bool),
400 Number(Number),
401}
402
403#[cfg(doc)]
404use crate::front::wgsl::lower::Lowerer;
405
406#[derive(Debug)]
407pub enum Expression<'a> {
408 Literal(Literal),
409 Ident(IdentExpr<'a>),
410
411 Construct {
426 ty: ConstructorType<'a>,
427 ty_span: Span,
428 components: Vec<Handle<Expression<'a>>>,
429 },
430 Unary {
431 op: crate::UnaryOperator,
432 expr: Handle<Expression<'a>>,
433 },
434 AddrOf(Handle<Expression<'a>>),
435 Deref(Handle<Expression<'a>>),
436 Binary {
437 op: crate::BinaryOperator,
438 left: Handle<Expression<'a>>,
439 right: Handle<Expression<'a>>,
440 },
441
442 Call {
457 function: Ident<'a>,
458 arguments: Vec<Handle<Expression<'a>>>,
459 },
460 Index {
461 base: Handle<Expression<'a>>,
462 index: Handle<Expression<'a>>,
463 },
464 Member {
465 base: Handle<Expression<'a>>,
466 field: Ident<'a>,
467 },
468 Bitcast {
469 expr: Handle<Expression<'a>>,
470 to: Handle<Type<'a>>,
471 ty_span: Span,
472 },
473}
474
475#[derive(Debug)]
476pub struct LocalVariable<'a> {
477 pub name: Ident<'a>,
478 pub ty: Option<Handle<Type<'a>>>,
479 pub init: Option<Handle<Expression<'a>>>,
480 pub handle: Handle<Local>,
481}
482
483#[derive(Debug)]
484pub struct Let<'a> {
485 pub name: Ident<'a>,
486 pub ty: Option<Handle<Type<'a>>>,
487 pub init: Handle<Expression<'a>>,
488 pub handle: Handle<Local>,
489}
490
491#[derive(Debug)]
492pub struct LocalConst<'a> {
493 pub name: Ident<'a>,
494 pub ty: Option<Handle<Type<'a>>>,
495 pub init: Handle<Expression<'a>>,
496 pub handle: Handle<Local>,
497}
498
499#[derive(Debug)]
500pub enum LocalDecl<'a> {
501 Var(LocalVariable<'a>),
502 Let(Let<'a>),
503 Const(LocalConst<'a>),
504}
505
506#[derive(Debug)]
507pub struct Local;