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::{Arena, FastIndexSet, Handle, Span};
8
9#[derive(Debug, Default)]
10pub struct TranslationUnit<'a> {
11 pub enable_extensions: EnableExtensions,
12 pub decls: Arena<GlobalDecl<'a>>,
13 pub expressions: Arena<Expression<'a>>,
25
26 pub diagnostic_filters: Arena<DiagnosticFilterNode>,
31 pub diagnostic_filter_leaf: Option<Handle<DiagnosticFilterNode>>,
36
37 pub doc_comments: Vec<&'a str>,
40}
41
42#[derive(Debug, Clone, Copy)]
43pub struct Ident<'a> {
44 pub name: &'a str,
45 pub span: Span,
46}
47
48#[derive(Debug)]
56pub enum IdentExpr<'a> {
57 Unresolved(&'a str),
74
75 Local(Handle<Local>),
77}
78
79#[derive(Debug)]
122pub struct TemplateElaboratedIdent<'a> {
123 pub ident: IdentExpr<'a>,
124 pub ident_span: Span,
125
126 pub template_list: Vec<Handle<Expression<'a>>>,
128 pub template_list_span: Span,
129}
130
131#[derive(Debug)]
146pub struct CallPhrase<'a> {
147 pub function: TemplateElaboratedIdent<'a>,
148 pub arguments: Vec<Handle<Expression<'a>>>,
149}
150
151#[derive(Debug)]
158pub struct Dependency<'a> {
159 pub ident: &'a str,
161
162 pub usage: Span,
164}
165
166impl Hash for Dependency<'_> {
167 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
168 self.ident.hash(state);
169 }
170}
171
172impl PartialEq for Dependency<'_> {
173 fn eq(&self, other: &Self) -> bool {
174 self.ident == other.ident
175 }
176}
177
178impl Eq for Dependency<'_> {}
179
180#[derive(Debug)]
182pub struct GlobalDecl<'a> {
183 pub kind: GlobalDeclKind<'a>,
184
185 pub dependencies: FastIndexSet<Dependency<'a>>,
188}
189
190#[derive(Debug)]
191pub enum GlobalDeclKind<'a> {
192 Fn(Function<'a>),
193 Var(GlobalVariable<'a>),
194 Const(Const<'a>),
195 Override(Override<'a>),
196 Struct(Struct<'a>),
197 Type(TypeAlias<'a>),
198 ConstAssert(Handle<Expression<'a>>),
199}
200
201#[derive(Debug)]
202pub struct FunctionArgument<'a> {
203 pub name: Ident<'a>,
204 pub ty: TemplateElaboratedIdent<'a>,
205 pub binding: Option<Binding<'a>>,
206 pub handle: Handle<Local>,
207}
208
209#[derive(Debug)]
210pub struct FunctionResult<'a> {
211 pub ty: TemplateElaboratedIdent<'a>,
212 pub binding: Option<Binding<'a>>,
213 pub must_use: bool,
214}
215
216#[derive(Debug)]
217pub struct EntryPoint<'a> {
218 pub stage: crate::ShaderStage,
219 pub early_depth_test: Option<crate::EarlyDepthTest>,
220 pub workgroup_size: Option<[Option<Handle<Expression<'a>>>; 3]>,
221 pub mesh_output_variable: Option<(&'a str, Span)>,
222 pub task_payload: Option<(&'a str, Span)>,
223 pub ray_incoming_payload: Option<(&'a str, Span)>,
224}
225
226#[cfg(doc)]
227use crate::front::wgsl::lower::{LocalExpressionContext, StatementContext};
228
229#[derive(Debug)]
230pub struct Function<'a> {
231 pub entry_point: Option<EntryPoint<'a>>,
232 pub name: Ident<'a>,
233 pub arguments: Vec<FunctionArgument<'a>>,
234 pub result: Option<FunctionResult<'a>>,
235 pub body: Block<'a>,
236 pub diagnostic_filter_leaf: Option<Handle<DiagnosticFilterNode>>,
237 pub doc_comments: Vec<&'a str>,
238}
239
240#[derive(Debug)]
241pub enum Binding<'a> {
242 BuiltIn(crate::BuiltIn),
243 Location {
244 location: Handle<Expression<'a>>,
245 interpolation: Option<crate::Interpolation>,
246 sampling: Option<crate::Sampling>,
247 blend_src: Option<Handle<Expression<'a>>>,
248 per_primitive: bool,
249 },
250}
251
252#[derive(Debug)]
253pub struct ResourceBinding<'a> {
254 pub group: Handle<Expression<'a>>,
255 pub binding: Handle<Expression<'a>>,
256}
257
258#[derive(Debug)]
259pub struct GlobalVariable<'a> {
260 pub name: Ident<'a>,
261
262 pub template_list: Vec<Handle<Expression<'a>>>,
265
266 pub binding: Option<ResourceBinding<'a>>,
268
269 pub ty: Option<TemplateElaboratedIdent<'a>>,
270 pub init: Option<Handle<Expression<'a>>>,
271 pub doc_comments: Vec<&'a str>,
272
273 pub memory_decorations: crate::MemoryDecorations,
275}
276
277#[derive(Debug)]
278pub struct StructMember<'a> {
279 pub name: Ident<'a>,
280 pub ty: TemplateElaboratedIdent<'a>,
281 pub binding: Option<Binding<'a>>,
282 pub align: Option<Handle<Expression<'a>>>,
283 pub size: Option<Handle<Expression<'a>>>,
284 pub doc_comments: Vec<&'a str>,
285}
286
287#[derive(Debug)]
288pub struct Struct<'a> {
289 pub name: Ident<'a>,
290 pub members: Vec<StructMember<'a>>,
291 pub doc_comments: Vec<&'a str>,
292}
293
294#[derive(Debug)]
295pub struct TypeAlias<'a> {
296 pub name: Ident<'a>,
297 pub ty: TemplateElaboratedIdent<'a>,
298}
299
300#[derive(Debug)]
301pub struct Const<'a> {
302 pub name: Ident<'a>,
303 pub ty: Option<TemplateElaboratedIdent<'a>>,
304 pub init: Handle<Expression<'a>>,
305 pub doc_comments: Vec<&'a str>,
306}
307
308#[derive(Debug)]
309pub struct Override<'a> {
310 pub name: Ident<'a>,
311 pub id: Option<Handle<Expression<'a>>>,
312 pub ty: Option<TemplateElaboratedIdent<'a>>,
313 pub init: Option<Handle<Expression<'a>>>,
314}
315
316#[derive(Debug, Default)]
317pub struct Block<'a> {
318 pub stmts: Vec<Statement<'a>>,
319}
320
321#[derive(Debug)]
322pub struct Statement<'a> {
323 pub kind: StatementKind<'a>,
324 pub span: Span,
325}
326
327#[derive(Debug)]
328pub enum StatementKind<'a> {
329 LocalDecl(LocalDecl<'a>),
330 Block(Block<'a>),
331 If {
332 condition: Handle<Expression<'a>>,
333 accept: Block<'a>,
334 reject: Block<'a>,
335 },
336 Switch {
337 selector: Handle<Expression<'a>>,
338 cases: Vec<SwitchCase<'a>>,
339 },
340 Loop {
341 body: Block<'a>,
342 continuing: Block<'a>,
343 break_if: Option<Handle<Expression<'a>>>,
344 },
345 Break,
346 Continue,
347 Return {
348 value: Option<Handle<Expression<'a>>>,
349 },
350 Kill,
351 Call(CallPhrase<'a>),
352 Assign {
353 target: Handle<Expression<'a>>,
354 op: Option<crate::BinaryOperator>,
355 value: Handle<Expression<'a>>,
356 },
357 Increment(Handle<Expression<'a>>),
358 Decrement(Handle<Expression<'a>>),
359 Phony(Handle<Expression<'a>>),
360 ConstAssert(Handle<Expression<'a>>),
361}
362
363#[derive(Debug)]
364pub enum SwitchValue<'a> {
365 Expr(Handle<Expression<'a>>),
366 Default,
367}
368
369#[derive(Debug)]
370pub struct SwitchCase<'a> {
371 pub value: SwitchValue<'a>,
372 pub body: Block<'a>,
373 pub fall_through: bool,
374}
375
376#[derive(Debug, Copy, Clone)]
377pub enum Literal {
378 Bool(bool),
379 Number(Number),
380}
381
382#[cfg(doc)]
383use crate::front::wgsl::lower::Lowerer;
384
385#[derive(Debug)]
386pub enum Expression<'a> {
387 Literal(Literal),
388 Ident(TemplateElaboratedIdent<'a>),
389 Unary {
390 op: crate::UnaryOperator,
391 expr: Handle<Expression<'a>>,
392 },
393 AddrOf(Handle<Expression<'a>>),
394 Deref(Handle<Expression<'a>>),
395 Binary {
396 op: crate::BinaryOperator,
397 left: Handle<Expression<'a>>,
398 right: Handle<Expression<'a>>,
399 },
400 Call(CallPhrase<'a>),
401 Index {
402 base: Handle<Expression<'a>>,
403 index: Handle<Expression<'a>>,
404 },
405 Member {
406 base: Handle<Expression<'a>>,
407 field: Ident<'a>,
408 },
409}
410
411#[derive(Debug)]
412pub struct LocalVariable<'a> {
413 pub name: Ident<'a>,
414 pub ty: Option<TemplateElaboratedIdent<'a>>,
415 pub init: Option<Handle<Expression<'a>>>,
416 pub handle: Handle<Local>,
417}
418
419#[derive(Debug)]
420pub struct Let<'a> {
421 pub name: Ident<'a>,
422 pub ty: Option<TemplateElaboratedIdent<'a>>,
423 pub init: Handle<Expression<'a>>,
424 pub handle: Handle<Local>,
425}
426
427#[derive(Debug)]
428pub struct LocalConst<'a> {
429 pub name: Ident<'a>,
430 pub ty: Option<TemplateElaboratedIdent<'a>>,
431 pub init: Handle<Expression<'a>>,
432 pub handle: Handle<Local>,
433}
434
435#[derive(Debug)]
436pub enum LocalDecl<'a> {
437 Var(LocalVariable<'a>),
438 Let(Let<'a>),
439 Const(LocalConst<'a>),
440}
441
442#[derive(Debug)]
443pub struct Local;