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 pub doc_comments: Vec<&'a str>,
47}
48
49#[derive(Debug, Clone, Copy)]
50pub struct Ident<'a> {
51 pub name: &'a str,
52 pub span: Span,
53}
54
55#[derive(Debug)]
56pub enum IdentExpr<'a> {
57 Unresolved(&'a str),
58 Local(Handle<Local>),
59}
60
61#[derive(Debug)]
68pub struct Dependency<'a> {
69 pub ident: &'a str,
71
72 pub usage: Span,
74}
75
76impl Hash for Dependency<'_> {
77 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
78 self.ident.hash(state);
79 }
80}
81
82impl PartialEq for Dependency<'_> {
83 fn eq(&self, other: &Self) -> bool {
84 self.ident == other.ident
85 }
86}
87
88impl Eq for Dependency<'_> {}
89
90#[derive(Debug)]
92pub struct GlobalDecl<'a> {
93 pub kind: GlobalDeclKind<'a>,
94
95 pub dependencies: FastIndexSet<Dependency<'a>>,
98}
99
100#[derive(Debug)]
101pub enum GlobalDeclKind<'a> {
102 Fn(Function<'a>),
103 Var(GlobalVariable<'a>),
104 Const(Const<'a>),
105 Override(Override<'a>),
106 Struct(Struct<'a>),
107 Type(TypeAlias<'a>),
108 ConstAssert(Handle<Expression<'a>>),
109}
110
111#[derive(Debug)]
112pub struct FunctionArgument<'a> {
113 pub name: Ident<'a>,
114 pub ty: Handle<Type<'a>>,
115 pub binding: Option<Binding<'a>>,
116 pub handle: Handle<Local>,
117}
118
119#[derive(Debug)]
120pub struct FunctionResult<'a> {
121 pub ty: Handle<Type<'a>>,
122 pub binding: Option<Binding<'a>>,
123 pub must_use: bool,
124}
125
126#[derive(Debug)]
127pub struct EntryPoint<'a> {
128 pub stage: crate::ShaderStage,
129 pub early_depth_test: Option<crate::EarlyDepthTest>,
130 pub workgroup_size: Option<[Option<Handle<Expression<'a>>>; 3]>,
131 pub mesh_output_variable: Option<(&'a str, Span)>,
132 pub task_payload: Option<(&'a str, Span)>,
133}
134
135#[cfg(doc)]
136use crate::front::wgsl::lower::{LocalExpressionContext, StatementContext};
137
138#[derive(Debug)]
139pub struct Function<'a> {
140 pub entry_point: Option<EntryPoint<'a>>,
141 pub name: Ident<'a>,
142 pub arguments: Vec<FunctionArgument<'a>>,
143 pub result: Option<FunctionResult<'a>>,
144 pub body: Block<'a>,
145 pub diagnostic_filter_leaf: Option<Handle<DiagnosticFilterNode>>,
146 pub doc_comments: Vec<&'a str>,
147}
148
149#[derive(Debug)]
150pub enum Binding<'a> {
151 BuiltIn(crate::BuiltIn),
152 Location {
153 location: Handle<Expression<'a>>,
154 interpolation: Option<crate::Interpolation>,
155 sampling: Option<crate::Sampling>,
156 blend_src: Option<Handle<Expression<'a>>>,
157 per_primitive: bool,
158 },
159}
160
161#[derive(Debug)]
162pub struct ResourceBinding<'a> {
163 pub group: Handle<Expression<'a>>,
164 pub binding: Handle<Expression<'a>>,
165}
166
167#[derive(Debug)]
168pub struct GlobalVariable<'a> {
169 pub name: Ident<'a>,
170 pub space: crate::AddressSpace,
171 pub binding: Option<ResourceBinding<'a>>,
172 pub ty: Option<Handle<Type<'a>>>,
173 pub init: Option<Handle<Expression<'a>>>,
174 pub doc_comments: Vec<&'a str>,
175}
176
177#[derive(Debug)]
178pub struct StructMember<'a> {
179 pub name: Ident<'a>,
180 pub ty: Handle<Type<'a>>,
181 pub binding: Option<Binding<'a>>,
182 pub align: Option<Handle<Expression<'a>>>,
183 pub size: Option<Handle<Expression<'a>>>,
184 pub doc_comments: Vec<&'a str>,
185}
186
187#[derive(Debug)]
188pub struct Struct<'a> {
189 pub name: Ident<'a>,
190 pub members: Vec<StructMember<'a>>,
191 pub doc_comments: Vec<&'a str>,
192}
193
194#[derive(Debug)]
195pub struct TypeAlias<'a> {
196 pub name: Ident<'a>,
197 pub ty: Handle<Type<'a>>,
198}
199
200#[derive(Debug)]
201pub struct Const<'a> {
202 pub name: Ident<'a>,
203 pub ty: Option<Handle<Type<'a>>>,
204 pub init: Handle<Expression<'a>>,
205 pub doc_comments: Vec<&'a str>,
206}
207
208#[derive(Debug)]
209pub struct Override<'a> {
210 pub name: Ident<'a>,
211 pub id: Option<Handle<Expression<'a>>>,
212 pub ty: Option<Handle<Type<'a>>>,
213 pub init: Option<Handle<Expression<'a>>>,
214}
215
216#[derive(Debug, Copy, Clone)]
221pub enum ArraySize<'a> {
222 Constant(Handle<Expression<'a>>),
224 Dynamic,
225}
226
227#[derive(Debug)]
228pub enum Type<'a> {
229 Scalar(Scalar),
230 Vector {
231 size: crate::VectorSize,
232 ty: Handle<Type<'a>>,
233 ty_span: Span,
234 },
235 Matrix {
236 columns: crate::VectorSize,
237 rows: crate::VectorSize,
238 ty: Handle<Type<'a>>,
239 ty_span: Span,
240 },
241 Atomic(Scalar),
242 Pointer {
243 base: Handle<Type<'a>>,
244 space: crate::AddressSpace,
245 },
246 Array {
247 base: Handle<Type<'a>>,
248 size: ArraySize<'a>,
249 },
250 Image {
251 dim: crate::ImageDimension,
252 arrayed: bool,
253 class: crate::ImageClass,
254 },
255 Sampler {
256 comparison: bool,
257 },
258 AccelerationStructure {
259 vertex_return: bool,
260 },
261 RayQuery {
262 vertex_return: bool,
263 },
264 RayDesc,
265 RayIntersection,
266 BindingArray {
267 base: Handle<Type<'a>>,
268 size: ArraySize<'a>,
269 },
270
271 User(Ident<'a>),
273}
274
275#[derive(Debug, Default)]
276pub struct Block<'a> {
277 pub stmts: Vec<Statement<'a>>,
278}
279
280#[derive(Debug)]
281pub struct Statement<'a> {
282 pub kind: StatementKind<'a>,
283 pub span: Span,
284}
285
286#[derive(Debug)]
287pub enum StatementKind<'a> {
288 LocalDecl(LocalDecl<'a>),
289 Block(Block<'a>),
290 If {
291 condition: Handle<Expression<'a>>,
292 accept: Block<'a>,
293 reject: Block<'a>,
294 },
295 Switch {
296 selector: Handle<Expression<'a>>,
297 cases: Vec<SwitchCase<'a>>,
298 },
299 Loop {
300 body: Block<'a>,
301 continuing: Block<'a>,
302 break_if: Option<Handle<Expression<'a>>>,
303 },
304 Break,
305 Continue,
306 Return {
307 value: Option<Handle<Expression<'a>>>,
308 },
309 Kill,
310 Call {
311 function: Ident<'a>,
312 arguments: Vec<Handle<Expression<'a>>>,
313 },
314 Assign {
315 target: Handle<Expression<'a>>,
316 op: Option<crate::BinaryOperator>,
317 value: Handle<Expression<'a>>,
318 },
319 Increment(Handle<Expression<'a>>),
320 Decrement(Handle<Expression<'a>>),
321 Phony(Handle<Expression<'a>>),
322 ConstAssert(Handle<Expression<'a>>),
323}
324
325#[derive(Debug)]
326pub enum SwitchValue<'a> {
327 Expr(Handle<Expression<'a>>),
328 Default,
329}
330
331#[derive(Debug)]
332pub struct SwitchCase<'a> {
333 pub value: SwitchValue<'a>,
334 pub body: Block<'a>,
335 pub fall_through: bool,
336}
337
338#[derive(Debug)]
359pub enum ConstructorType<'a> {
360 Scalar(Scalar),
362
363 PartialVector { size: crate::VectorSize },
366
367 Vector {
370 size: crate::VectorSize,
371 ty: Handle<Type<'a>>,
372 ty_span: Span,
373 },
374
375 PartialMatrix {
378 columns: crate::VectorSize,
379 rows: crate::VectorSize,
380 },
381
382 Matrix {
385 columns: crate::VectorSize,
386 rows: crate::VectorSize,
387 ty: Handle<Type<'a>>,
388 ty_span: Span,
389 },
390
391 PartialArray,
394
395 Array {
398 base: Handle<Type<'a>>,
399 size: ArraySize<'a>,
400 },
401
402 Type(Handle<crate::Type>),
407}
408
409#[derive(Debug, Copy, Clone)]
410pub enum Literal {
411 Bool(bool),
412 Number(Number),
413}
414
415#[cfg(doc)]
416use crate::front::wgsl::lower::Lowerer;
417
418#[derive(Debug)]
419pub enum Expression<'a> {
420 Literal(Literal),
421 Ident(IdentExpr<'a>),
422
423 Construct {
438 ty: ConstructorType<'a>,
439 ty_span: Span,
440 components: Vec<Handle<Expression<'a>>>,
441 },
442 Unary {
443 op: crate::UnaryOperator,
444 expr: Handle<Expression<'a>>,
445 },
446 AddrOf(Handle<Expression<'a>>),
447 Deref(Handle<Expression<'a>>),
448 Binary {
449 op: crate::BinaryOperator,
450 left: Handle<Expression<'a>>,
451 right: Handle<Expression<'a>>,
452 },
453
454 Call {
469 function: Ident<'a>,
470 arguments: Vec<Handle<Expression<'a>>>,
471 },
472 Index {
473 base: Handle<Expression<'a>>,
474 index: Handle<Expression<'a>>,
475 },
476 Member {
477 base: Handle<Expression<'a>>,
478 field: Ident<'a>,
479 },
480 Bitcast {
481 expr: Handle<Expression<'a>>,
482 to: Handle<Type<'a>>,
483 ty_span: Span,
484 },
485}
486
487#[derive(Debug)]
488pub struct LocalVariable<'a> {
489 pub name: Ident<'a>,
490 pub ty: Option<Handle<Type<'a>>>,
491 pub init: Option<Handle<Expression<'a>>>,
492 pub handle: Handle<Local>,
493}
494
495#[derive(Debug)]
496pub struct Let<'a> {
497 pub name: Ident<'a>,
498 pub ty: Option<Handle<Type<'a>>>,
499 pub init: Handle<Expression<'a>>,
500 pub handle: Handle<Local>,
501}
502
503#[derive(Debug)]
504pub struct LocalConst<'a> {
505 pub name: Ident<'a>,
506 pub ty: Option<Handle<Type<'a>>>,
507 pub init: Handle<Expression<'a>>,
508 pub handle: Handle<Local>,
509}
510
511#[derive(Debug)]
512pub enum LocalDecl<'a> {
513 Var(LocalVariable<'a>),
514 Let(Let<'a>),
515 Const(LocalConst<'a>),
516}
517
518#[derive(Debug)]
519pub struct Local;