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
274#[derive(Debug)]
275pub struct StructMember<'a> {
276 pub name: Ident<'a>,
277 pub ty: TemplateElaboratedIdent<'a>,
278 pub binding: Option<Binding<'a>>,
279 pub align: Option<Handle<Expression<'a>>>,
280 pub size: Option<Handle<Expression<'a>>>,
281 pub doc_comments: Vec<&'a str>,
282}
283
284#[derive(Debug)]
285pub struct Struct<'a> {
286 pub name: Ident<'a>,
287 pub members: Vec<StructMember<'a>>,
288 pub doc_comments: Vec<&'a str>,
289}
290
291#[derive(Debug)]
292pub struct TypeAlias<'a> {
293 pub name: Ident<'a>,
294 pub ty: TemplateElaboratedIdent<'a>,
295}
296
297#[derive(Debug)]
298pub struct Const<'a> {
299 pub name: Ident<'a>,
300 pub ty: Option<TemplateElaboratedIdent<'a>>,
301 pub init: Handle<Expression<'a>>,
302 pub doc_comments: Vec<&'a str>,
303}
304
305#[derive(Debug)]
306pub struct Override<'a> {
307 pub name: Ident<'a>,
308 pub id: Option<Handle<Expression<'a>>>,
309 pub ty: Option<TemplateElaboratedIdent<'a>>,
310 pub init: Option<Handle<Expression<'a>>>,
311}
312
313#[derive(Debug, Default)]
314pub struct Block<'a> {
315 pub stmts: Vec<Statement<'a>>,
316}
317
318#[derive(Debug)]
319pub struct Statement<'a> {
320 pub kind: StatementKind<'a>,
321 pub span: Span,
322}
323
324#[derive(Debug)]
325pub enum StatementKind<'a> {
326 LocalDecl(LocalDecl<'a>),
327 Block(Block<'a>),
328 If {
329 condition: Handle<Expression<'a>>,
330 accept: Block<'a>,
331 reject: Block<'a>,
332 },
333 Switch {
334 selector: Handle<Expression<'a>>,
335 cases: Vec<SwitchCase<'a>>,
336 },
337 Loop {
338 body: Block<'a>,
339 continuing: Block<'a>,
340 break_if: Option<Handle<Expression<'a>>>,
341 },
342 Break,
343 Continue,
344 Return {
345 value: Option<Handle<Expression<'a>>>,
346 },
347 Kill,
348 Call(CallPhrase<'a>),
349 Assign {
350 target: Handle<Expression<'a>>,
351 op: Option<crate::BinaryOperator>,
352 value: Handle<Expression<'a>>,
353 },
354 Increment(Handle<Expression<'a>>),
355 Decrement(Handle<Expression<'a>>),
356 Phony(Handle<Expression<'a>>),
357 ConstAssert(Handle<Expression<'a>>),
358}
359
360#[derive(Debug)]
361pub enum SwitchValue<'a> {
362 Expr(Handle<Expression<'a>>),
363 Default,
364}
365
366#[derive(Debug)]
367pub struct SwitchCase<'a> {
368 pub value: SwitchValue<'a>,
369 pub body: Block<'a>,
370 pub fall_through: bool,
371}
372
373#[derive(Debug, Copy, Clone)]
374pub enum Literal {
375 Bool(bool),
376 Number(Number),
377}
378
379#[cfg(doc)]
380use crate::front::wgsl::lower::Lowerer;
381
382#[derive(Debug)]
383pub enum Expression<'a> {
384 Literal(Literal),
385 Ident(TemplateElaboratedIdent<'a>),
386 Unary {
387 op: crate::UnaryOperator,
388 expr: Handle<Expression<'a>>,
389 },
390 AddrOf(Handle<Expression<'a>>),
391 Deref(Handle<Expression<'a>>),
392 Binary {
393 op: crate::BinaryOperator,
394 left: Handle<Expression<'a>>,
395 right: Handle<Expression<'a>>,
396 },
397 Call(CallPhrase<'a>),
398 Index {
399 base: Handle<Expression<'a>>,
400 index: Handle<Expression<'a>>,
401 },
402 Member {
403 base: Handle<Expression<'a>>,
404 field: Ident<'a>,
405 },
406}
407
408#[derive(Debug)]
409pub struct LocalVariable<'a> {
410 pub name: Ident<'a>,
411 pub ty: Option<TemplateElaboratedIdent<'a>>,
412 pub init: Option<Handle<Expression<'a>>>,
413 pub handle: Handle<Local>,
414}
415
416#[derive(Debug)]
417pub struct Let<'a> {
418 pub name: Ident<'a>,
419 pub ty: Option<TemplateElaboratedIdent<'a>>,
420 pub init: Handle<Expression<'a>>,
421 pub handle: Handle<Local>,
422}
423
424#[derive(Debug)]
425pub struct LocalConst<'a> {
426 pub name: Ident<'a>,
427 pub ty: Option<TemplateElaboratedIdent<'a>>,
428 pub init: Handle<Expression<'a>>,
429 pub handle: Handle<Local>,
430}
431
432#[derive(Debug)]
433pub enum LocalDecl<'a> {
434 Var(LocalVariable<'a>),
435 Let(Let<'a>),
436 Const(LocalConst<'a>),
437}
438
439#[derive(Debug)]
440pub struct Local;