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}
132
133#[cfg(doc)]
134use crate::front::wgsl::lower::{LocalExpressionContext, StatementContext};
135
136#[derive(Debug)]
137pub struct Function<'a> {
138 pub entry_point: Option<EntryPoint<'a>>,
139 pub name: Ident<'a>,
140 pub arguments: Vec<FunctionArgument<'a>>,
141 pub result: Option<FunctionResult<'a>>,
142 pub body: Block<'a>,
143 pub diagnostic_filter_leaf: Option<Handle<DiagnosticFilterNode>>,
144 pub doc_comments: Vec<&'a str>,
145}
146
147#[derive(Debug)]
148pub enum Binding<'a> {
149 BuiltIn(crate::BuiltIn),
150 Location {
151 location: Handle<Expression<'a>>,
152 interpolation: Option<crate::Interpolation>,
153 sampling: Option<crate::Sampling>,
154 blend_src: Option<Handle<Expression<'a>>>,
155 },
156}
157
158#[derive(Debug)]
159pub struct ResourceBinding<'a> {
160 pub group: Handle<Expression<'a>>,
161 pub binding: Handle<Expression<'a>>,
162}
163
164#[derive(Debug)]
165pub struct GlobalVariable<'a> {
166 pub name: Ident<'a>,
167 pub space: crate::AddressSpace,
168 pub binding: Option<ResourceBinding<'a>>,
169 pub ty: Option<Handle<Type<'a>>>,
170 pub init: Option<Handle<Expression<'a>>>,
171 pub doc_comments: Vec<&'a str>,
172}
173
174#[derive(Debug)]
175pub struct StructMember<'a> {
176 pub name: Ident<'a>,
177 pub ty: Handle<Type<'a>>,
178 pub binding: Option<Binding<'a>>,
179 pub align: Option<Handle<Expression<'a>>>,
180 pub size: Option<Handle<Expression<'a>>>,
181 pub doc_comments: Vec<&'a str>,
182}
183
184#[derive(Debug)]
185pub struct Struct<'a> {
186 pub name: Ident<'a>,
187 pub members: Vec<StructMember<'a>>,
188 pub doc_comments: Vec<&'a str>,
189}
190
191#[derive(Debug)]
192pub struct TypeAlias<'a> {
193 pub name: Ident<'a>,
194 pub ty: Handle<Type<'a>>,
195}
196
197#[derive(Debug)]
198pub struct Const<'a> {
199 pub name: Ident<'a>,
200 pub ty: Option<Handle<Type<'a>>>,
201 pub init: Handle<Expression<'a>>,
202 pub doc_comments: Vec<&'a str>,
203}
204
205#[derive(Debug)]
206pub struct Override<'a> {
207 pub name: Ident<'a>,
208 pub id: Option<Handle<Expression<'a>>>,
209 pub ty: Option<Handle<Type<'a>>>,
210 pub init: Option<Handle<Expression<'a>>>,
211}
212
213#[derive(Debug, Copy, Clone)]
218pub enum ArraySize<'a> {
219 Constant(Handle<Expression<'a>>),
221 Dynamic,
222}
223
224#[derive(Debug)]
225pub enum Type<'a> {
226 Scalar(Scalar),
227 Vector {
228 size: crate::VectorSize,
229 ty: Handle<Type<'a>>,
230 ty_span: Span,
231 },
232 Matrix {
233 columns: crate::VectorSize,
234 rows: crate::VectorSize,
235 ty: Handle<Type<'a>>,
236 ty_span: Span,
237 },
238 Atomic(Scalar),
239 Pointer {
240 base: Handle<Type<'a>>,
241 space: crate::AddressSpace,
242 },
243 Array {
244 base: Handle<Type<'a>>,
245 size: ArraySize<'a>,
246 },
247 Image {
248 dim: crate::ImageDimension,
249 arrayed: bool,
250 class: crate::ImageClass,
251 },
252 Sampler {
253 comparison: bool,
254 },
255 AccelerationStructure {
256 vertex_return: bool,
257 },
258 RayQuery {
259 vertex_return: bool,
260 },
261 RayDesc,
262 RayIntersection,
263 BindingArray {
264 base: Handle<Type<'a>>,
265 size: ArraySize<'a>,
266 },
267
268 User(Ident<'a>),
270}
271
272#[derive(Debug, Default)]
273pub struct Block<'a> {
274 pub stmts: Vec<Statement<'a>>,
275}
276
277#[derive(Debug)]
278pub struct Statement<'a> {
279 pub kind: StatementKind<'a>,
280 pub span: Span,
281}
282
283#[derive(Debug)]
284pub enum StatementKind<'a> {
285 LocalDecl(LocalDecl<'a>),
286 Block(Block<'a>),
287 If {
288 condition: Handle<Expression<'a>>,
289 accept: Block<'a>,
290 reject: Block<'a>,
291 },
292 Switch {
293 selector: Handle<Expression<'a>>,
294 cases: Vec<SwitchCase<'a>>,
295 },
296 Loop {
297 body: Block<'a>,
298 continuing: Block<'a>,
299 break_if: Option<Handle<Expression<'a>>>,
300 },
301 Break,
302 Continue,
303 Return {
304 value: Option<Handle<Expression<'a>>>,
305 },
306 Kill,
307 Call {
308 function: Ident<'a>,
309 arguments: Vec<Handle<Expression<'a>>>,
310 },
311 Assign {
312 target: Handle<Expression<'a>>,
313 op: Option<crate::BinaryOperator>,
314 value: Handle<Expression<'a>>,
315 },
316 Increment(Handle<Expression<'a>>),
317 Decrement(Handle<Expression<'a>>),
318 Phony(Handle<Expression<'a>>),
319 ConstAssert(Handle<Expression<'a>>),
320}
321
322#[derive(Debug)]
323pub enum SwitchValue<'a> {
324 Expr(Handle<Expression<'a>>),
325 Default,
326}
327
328#[derive(Debug)]
329pub struct SwitchCase<'a> {
330 pub value: SwitchValue<'a>,
331 pub body: Block<'a>,
332 pub fall_through: bool,
333}
334
335#[derive(Debug)]
356pub enum ConstructorType<'a> {
357 Scalar(Scalar),
359
360 PartialVector { size: crate::VectorSize },
363
364 Vector {
367 size: crate::VectorSize,
368 ty: Handle<Type<'a>>,
369 ty_span: Span,
370 },
371
372 PartialMatrix {
375 columns: crate::VectorSize,
376 rows: crate::VectorSize,
377 },
378
379 Matrix {
382 columns: crate::VectorSize,
383 rows: crate::VectorSize,
384 ty: Handle<Type<'a>>,
385 ty_span: Span,
386 },
387
388 PartialArray,
391
392 Array {
395 base: Handle<Type<'a>>,
396 size: ArraySize<'a>,
397 },
398
399 Type(Handle<crate::Type>),
404}
405
406#[derive(Debug, Copy, Clone)]
407pub enum Literal {
408 Bool(bool),
409 Number(Number),
410}
411
412#[cfg(doc)]
413use crate::front::wgsl::lower::Lowerer;
414
415#[derive(Debug)]
416pub enum Expression<'a> {
417 Literal(Literal),
418 Ident(IdentExpr<'a>),
419
420 Construct {
435 ty: ConstructorType<'a>,
436 ty_span: Span,
437 components: Vec<Handle<Expression<'a>>>,
438 },
439 Unary {
440 op: crate::UnaryOperator,
441 expr: Handle<Expression<'a>>,
442 },
443 AddrOf(Handle<Expression<'a>>),
444 Deref(Handle<Expression<'a>>),
445 Binary {
446 op: crate::BinaryOperator,
447 left: Handle<Expression<'a>>,
448 right: Handle<Expression<'a>>,
449 },
450
451 Call {
466 function: Ident<'a>,
467 arguments: Vec<Handle<Expression<'a>>>,
468 },
469 Index {
470 base: Handle<Expression<'a>>,
471 index: Handle<Expression<'a>>,
472 },
473 Member {
474 base: Handle<Expression<'a>>,
475 field: Ident<'a>,
476 },
477 Bitcast {
478 expr: Handle<Expression<'a>>,
479 to: Handle<Type<'a>>,
480 ty_span: Span,
481 },
482}
483
484#[derive(Debug)]
485pub struct LocalVariable<'a> {
486 pub name: Ident<'a>,
487 pub ty: Option<Handle<Type<'a>>>,
488 pub init: Option<Handle<Expression<'a>>>,
489 pub handle: Handle<Local>,
490}
491
492#[derive(Debug)]
493pub struct Let<'a> {
494 pub name: Ident<'a>,
495 pub ty: Option<Handle<Type<'a>>>,
496 pub init: Handle<Expression<'a>>,
497 pub handle: Handle<Local>,
498}
499
500#[derive(Debug)]
501pub struct LocalConst<'a> {
502 pub name: Ident<'a>,
503 pub ty: Option<Handle<Type<'a>>>,
504 pub init: Handle<Expression<'a>>,
505 pub handle: Handle<Local>,
506}
507
508#[derive(Debug)]
509pub enum LocalDecl<'a> {
510 Var(LocalVariable<'a>),
511 Let(Let<'a>),
512 Const(LocalConst<'a>),
513}
514
515#[derive(Debug)]
516pub struct Local;