1use std::sync::{Arc, RwLock, RwLockReadGuard};
22
23use derive_more::{From, IsVariant, Unwrap};
24
25pub use crate::span::{Span, Spanned};
26
27pub use wgsl_types::syntax::*;
28
29#[cfg(feature = "tokrepr")]
30use tokrepr::TokRepr;
31
32#[cfg(feature = "serde")]
33use serde::{Deserialize, Serialize};
34
35#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
36#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
37#[derive(Default, Clone, Debug, PartialEq)]
38pub struct TranslationUnit {
39 pub imports: Vec<ImportStatement>,
40 pub global_directives: Vec<GlobalDirective>,
41 pub global_declarations: Vec<GlobalDeclarationNode>,
42}
43
44#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
51#[derive(Clone, Debug)]
52pub struct Ident(Arc<RwLock<String>>);
53
54impl Ident {
55 pub fn new(name: String) -> Ident {
57 Ident(Arc::new(RwLock::new(name)))
59 }
60 pub fn name(&self) -> RwLockReadGuard<'_, String> {
62 self.0.read().unwrap()
63 }
64 pub fn rename(&mut self, name: String) {
66 *self.0.write().unwrap() = name;
67 }
68 pub fn use_count(&self) -> usize {
70 Arc::<_>::strong_count(&self.0)
71 }
72}
73
74impl From<String> for Ident {
75 fn from(name: String) -> Self {
76 Ident::new(name)
77 }
78}
79
80impl PartialEq for Ident {
82 fn eq(&self, other: &Self) -> bool {
83 Arc::ptr_eq(&self.0, &other.0)
84 }
85}
86
87impl Eq for Ident {}
89
90impl std::hash::Hash for Ident {
92 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
93 std::ptr::hash(&*self.0, state)
94 }
95}
96
97#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
99#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
100#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, IsVariant)]
101pub enum Visibility {
102 Private,
103 #[default]
104 Package,
105 Public,
106}
107
108#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
110#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
111#[derive(Clone, Debug, PartialEq)]
112pub struct ImportStatement {
113 pub attributes: Attributes,
114 pub visibility: Visibility,
115 pub path: Option<ModulePath>,
116 pub content: ImportContent,
117}
118
119#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
121#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
122#[derive(Clone, Debug, PartialEq, Eq, Hash, IsVariant)]
123pub enum PathOrigin {
124 Absolute,
126 Relative(usize),
128 Package(String),
130}
131
132#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
134#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
135#[derive(Clone, Debug, PartialEq, Eq, Hash)]
136pub struct ModulePath {
137 pub origin: PathOrigin,
138 pub components: Vec<String>,
139}
140
141#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
143#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
144#[derive(Clone, Debug, PartialEq)]
145pub struct Import {
146 pub path: Vec<String>,
147 pub content: ImportContent,
148}
149
150#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
152#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
153#[derive(Clone, Debug, PartialEq, IsVariant)]
154pub enum ImportContent {
155 Item(ImportItem),
156 Collection(Vec<Import>),
157}
158
159#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
161#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
162#[derive(Clone, Debug, PartialEq)]
163pub struct ImportItem {
164 pub ident: Ident,
165 pub rename: Option<Ident>,
166}
167
168#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
169#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
170#[derive(Clone, Debug, PartialEq, From, IsVariant, Unwrap)]
171pub enum GlobalDirective {
172 Diagnostic(DiagnosticDirective),
173 Enable(EnableDirective),
174 Requires(RequiresDirective),
175}
176
177#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
178#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
179#[derive(Clone, Debug, PartialEq)]
180pub struct DiagnosticDirective {
181 pub attributes: Attributes,
183 pub severity: DiagnosticSeverity,
184 pub rule_name: String,
185}
186
187#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
188#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
189#[derive(Clone, Debug, PartialEq)]
190pub struct EnableDirective {
191 pub attributes: Attributes,
193 pub extensions: Vec<String>,
194}
195
196#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
197#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
198#[derive(Clone, Debug, PartialEq)]
199pub struct RequiresDirective {
200 pub attributes: Attributes,
202 pub extensions: Vec<String>,
203}
204
205#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
206#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
207#[derive(Clone, Debug, PartialEq, From, IsVariant, Unwrap)]
208pub enum GlobalDeclaration {
209 Void,
210 Declaration(Declaration),
211 TypeAlias(TypeAlias),
212 Struct(Struct),
213 Function(Function),
214 ConstAssert(ConstAssert),
215 Compound(CompoundGlobalDeclaration),
217}
218
219pub type GlobalDeclarationNode = Spanned<GlobalDeclaration>;
220
221#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
222#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
223#[derive(Clone, Debug, PartialEq)]
224pub struct Declaration {
225 pub attributes: Attributes,
226 pub visibility: Visibility,
227 pub kind: DeclarationKind,
228 pub ident: Ident,
229 pub ty: Option<TypeExpression>,
230 pub initializer: Option<ExpressionNode>,
231}
232
233#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
234#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
235#[derive(Clone, Copy, Debug, PartialEq, Eq, IsVariant)]
236pub enum DeclarationKind {
237 Const,
238 Override,
239 Let,
240 Var(Option<(AddressSpace, Option<AccessMode>)>), }
242
243#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
244#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
245#[derive(Clone, Debug, PartialEq)]
246pub struct TypeAlias {
247 pub attributes: Attributes,
249 pub visibility: Visibility,
250 pub ident: Ident,
251 pub ty: TypeExpression,
252}
253
254#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
255#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
256#[derive(Clone, Debug, PartialEq)]
257pub struct Struct {
258 pub attributes: Attributes,
260 pub visibility: Visibility,
261 pub ident: Ident,
262 pub members: Vec<StructMemberNode>,
263}
264
265#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
266#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
267#[derive(Clone, Debug, PartialEq)]
268pub struct StructMember {
269 pub attributes: Attributes,
270 pub ident: Ident,
271 pub ty: TypeExpression,
272}
273
274pub type StructMemberNode = Spanned<StructMember>;
275
276#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
277#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
278#[derive(Clone, Debug, PartialEq)]
279pub struct Function {
280 pub attributes: Attributes,
281 pub visibility: Visibility,
282 pub ident: Ident,
283 pub parameters: Vec<FormalParameter>,
284 pub return_attributes: Attributes,
285 pub return_type: Option<TypeExpression>,
286 pub body: CompoundStatement,
287}
288
289#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
290#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
291#[derive(Clone, Debug, PartialEq)]
292pub struct FormalParameter {
293 pub attributes: Attributes,
294 pub ident: Ident,
295 pub ty: TypeExpression,
296}
297
298#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
299#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
300#[derive(Clone, Debug, PartialEq)]
301pub struct ConstAssert {
302 pub attributes: Attributes,
304 pub expression: ExpressionNode,
305}
306
307#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
309#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
310#[derive(Clone, Debug, PartialEq)]
311pub struct CompoundGlobalDeclaration {
312 pub attributes: Attributes,
313 pub body: Vec<GlobalDeclarationNode>,
314}
315
316#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
317#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
318#[derive(Clone, Debug, PartialEq)]
319pub struct DiagnosticAttribute {
320 pub severity: DiagnosticSeverity,
321 pub rule: String,
322}
323
324#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
325#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
326#[derive(Clone, Debug, PartialEq)]
327pub struct InterpolateAttribute {
328 pub ty: InterpolationType,
329 pub sampling: Option<InterpolationSampling>,
330}
331
332#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
333#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
334#[derive(Clone, Debug, PartialEq)]
335pub struct WorkgroupSizeAttribute {
336 pub x: ExpressionNode,
337 pub y: Option<ExpressionNode>,
338 pub z: Option<ExpressionNode>,
339}
340
341#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
342#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
343#[derive(Clone, Debug, PartialEq)]
344pub struct CustomAttribute {
345 pub name: String,
346 pub arguments: Option<Vec<ExpressionNode>>,
347}
348
349#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
350#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
351#[derive(Clone, Debug, PartialEq, From, IsVariant, Unwrap)]
352pub enum Attribute {
353 Align(ExpressionNode),
354 Binding(ExpressionNode),
355 BlendSrc(ExpressionNode),
356 #[from]
357 Builtin(BuiltinValue),
358 Const,
359 #[from]
360 Diagnostic(DiagnosticAttribute),
361 Group(ExpressionNode),
362 Id(ExpressionNode),
363 #[from]
364 Interpolate(InterpolateAttribute),
365 Invariant,
366 Location(ExpressionNode),
367 MustUse,
368 Size(ExpressionNode),
369 #[from]
370 WorkgroupSize(WorkgroupSizeAttribute),
371 Vertex,
372 Fragment,
373 Compute,
374
375 If(ExpressionNode),
377 Elif(ExpressionNode),
379 Else,
381
382 #[cfg(feature = "generics")]
384 #[from]
385 Type(TypeConstraint),
386
387 #[cfg(feature = "naga-ext")]
389 Task,
390 #[cfg(feature = "naga-ext")]
392 Payload(ExpressionNode),
393 #[cfg(feature = "naga-ext")]
395 Mesh(ExpressionNode),
396 #[cfg(feature = "naga-ext")]
398 RayGeneration,
399 #[cfg(feature = "naga-ext")]
401 AnyHit,
402 #[cfg(feature = "naga-ext")]
404 ClosestHit,
405 #[cfg(feature = "naga-ext")]
407 Miss,
408 #[cfg(feature = "naga-ext")]
410 IncomingPayload(ExpressionNode),
411 #[cfg(feature = "naga-ext")]
413 EarlyDepthTest(Option<ConservativeDepth>),
414
415 #[from]
416 Custom(CustomAttribute),
417}
418
419impl Attribute {
420 pub fn is_entry_point(&self) -> bool {
421 match self {
422 Attribute::Vertex | Attribute::Fragment | Attribute::Compute => true,
423
424 #[cfg(feature = "naga-ext")]
426 Attribute::Task
427 | Attribute::Mesh(_)
428 | Attribute::RayGeneration
429 | Attribute::AnyHit
430 | Attribute::ClosestHit
431 | Attribute::Miss => true,
432
433 _ => false,
434 }
435 }
436
437 pub fn is_condcomp(&self) -> bool {
438 matches!(
439 self,
440 Attribute::If(_) | Attribute::Elif(_) | Attribute::Else
441 )
442 }
443}
444
445pub type AttributeNode = Spanned<Attribute>;
446
447#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
448#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
449#[derive(Clone, Debug, PartialEq, From)]
450pub struct TypeConstraint {
451 pub ident: Ident,
452 pub variants: Vec<TypeExpression>,
453}
454
455pub type Attributes = Vec<AttributeNode>;
456
457#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
458#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
459#[derive(Clone, Debug, PartialEq, From, IsVariant, Unwrap)]
460pub enum Expression {
461 Literal(LiteralExpression),
462 Parenthesized(ParenthesizedExpression),
463 NamedComponent(NamedComponentExpression),
464 Indexing(IndexingExpression),
465 Unary(UnaryExpression),
466 Binary(BinaryExpression),
467 FunctionCall(FunctionCallExpression),
468 TypeOrIdentifier(TypeExpression),
469}
470
471pub type ExpressionNode = Spanned<Expression>;
472
473#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
474#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
475#[derive(Clone, Copy, Debug, PartialEq, From, IsVariant, Unwrap)]
476pub enum LiteralExpression {
477 Bool(bool),
478 AbstractInt(i64),
479 AbstractFloat(f64),
480 I32(i32),
481 U32(u32),
482 F32(f32),
483 #[from(skip)]
484 F16(f32),
485
486 #[cfg(feature = "naga-ext")]
488 #[from(skip)]
489 I64(i64),
490 #[cfg(feature = "naga-ext")]
492 #[from(skip)]
493 U64(u64),
494 #[cfg(feature = "naga-ext")]
496 #[from(skip)]
497 F64(f64),
498}
499
500#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
501#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
502#[derive(Clone, Debug, PartialEq)]
503pub struct ParenthesizedExpression {
504 pub expression: ExpressionNode,
505}
506
507#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
508#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
509#[derive(Clone, Debug, PartialEq)]
510pub struct NamedComponentExpression {
511 pub base: ExpressionNode,
512 pub component: Ident,
513}
514
515#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
516#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
517#[derive(Clone, Debug, PartialEq)]
518pub struct IndexingExpression {
519 pub base: ExpressionNode,
520 pub index: ExpressionNode,
521}
522
523#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
524#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
525#[derive(Clone, Debug, PartialEq)]
526pub struct UnaryExpression {
527 pub operator: UnaryOperator,
528 pub operand: ExpressionNode,
529}
530
531#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
532#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
533#[derive(Clone, Debug, PartialEq)]
534pub struct BinaryExpression {
535 pub operator: BinaryOperator,
536 pub left: ExpressionNode,
537 pub right: ExpressionNode,
538}
539
540#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
541#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
542#[derive(Clone, Debug, PartialEq)]
543pub struct FunctionCall {
544 pub ty: TypeExpression,
545 pub arguments: Vec<ExpressionNode>,
546}
547
548pub type FunctionCallExpression = FunctionCall;
549
550#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
551#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
552#[derive(Clone, Debug, PartialEq)]
553pub struct TypeExpression {
554 pub path: Option<ModulePath>,
556 pub ident: Ident,
557 pub template_args: TemplateArgs,
558}
559
560#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
561#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
562#[derive(Clone, Debug, PartialEq)]
563pub struct TemplateArg {
564 pub expression: ExpressionNode,
565}
566pub type TemplateArgs = Option<Vec<TemplateArg>>;
567
568#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
569#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
570#[derive(Clone, Debug, PartialEq, From, IsVariant, Unwrap)]
571pub enum Statement {
572 Void,
573 Compound(CompoundStatement),
574 Assignment(AssignmentStatement),
575 Increment(IncrementStatement),
576 Decrement(DecrementStatement),
577 If(IfStatement),
578 Switch(SwitchStatement),
579 Loop(LoopStatement),
580 For(ForStatement),
581 While(WhileStatement),
582 Break(BreakStatement),
583 Continue(ContinueStatement),
584 Return(ReturnStatement),
585 Discard(DiscardStatement),
586 FunctionCall(FunctionCallStatement),
587 ConstAssert(ConstAssertStatement),
588 Declaration(DeclarationStatement),
589}
590
591pub type StatementNode = Spanned<Statement>;
592
593#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
594#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
595#[derive(Clone, Debug, PartialEq, Default)]
596pub struct CompoundStatement {
597 pub attributes: Attributes,
598 pub statements: Vec<StatementNode>,
599}
600
601#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
602#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
603#[derive(Clone, Debug, PartialEq)]
604pub struct AssignmentStatement {
605 pub attributes: Attributes,
607 pub operator: AssignmentOperator,
608 pub lhs: ExpressionNode,
609 pub rhs: ExpressionNode,
610}
611
612#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
613#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
614#[derive(Clone, Debug, PartialEq)]
615pub struct IncrementStatement {
616 pub attributes: Attributes,
618 pub expression: ExpressionNode,
619}
620
621#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
622#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
623#[derive(Clone, Debug, PartialEq)]
624pub struct DecrementStatement {
625 pub attributes: Attributes,
627 pub expression: ExpressionNode,
628}
629
630#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
631#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
632#[derive(Clone, Debug, PartialEq)]
633pub struct IfStatement {
634 pub attributes: Attributes,
635 pub if_clause: IfClause,
636 pub else_if_clauses: Vec<ElseIfClause>,
637 pub else_clause: Option<ElseClause>,
638}
639
640#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
641#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
642#[derive(Clone, Debug, PartialEq)]
643pub struct IfClause {
644 pub expression: ExpressionNode,
645 pub body: CompoundStatement,
646}
647
648#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
649#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
650#[derive(Clone, Debug, PartialEq)]
651pub struct ElseIfClause {
652 pub attributes: Attributes,
654 pub expression: ExpressionNode,
655 pub body: CompoundStatement,
656}
657
658#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
659#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
660#[derive(Clone, Debug, PartialEq)]
661pub struct ElseClause {
662 pub attributes: Attributes,
664 pub body: CompoundStatement,
665}
666
667#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
668#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
669#[derive(Clone, Debug, PartialEq)]
670pub struct SwitchStatement {
671 pub attributes: Attributes,
672 pub expression: ExpressionNode,
673 pub body_attributes: Attributes,
674 pub clauses: Vec<SwitchClause>,
675}
676
677#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
678#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
679#[derive(Clone, Debug, PartialEq)]
680pub struct SwitchClause {
681 pub attributes: Attributes,
683 pub case_selectors: Vec<CaseSelector>,
684 pub body: CompoundStatement,
685}
686
687#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
688#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
689#[derive(Clone, Debug, PartialEq, From, IsVariant, Unwrap)]
690pub enum CaseSelector {
691 Default,
692 Expression(ExpressionNode),
693}
694
695#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
696#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
697#[derive(Clone, Debug, PartialEq)]
698pub struct LoopStatement {
699 pub attributes: Attributes,
700 pub body: CompoundStatement,
701 pub continuing: Option<ContinuingStatement>,
705}
706
707#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
708#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
709#[derive(Clone, Debug, PartialEq)]
710pub struct ContinuingStatement {
711 pub attributes: Attributes,
713 pub body: CompoundStatement,
714 pub break_if: Option<BreakIfStatement>,
718}
719
720#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
721#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
722#[derive(Clone, Debug, PartialEq)]
723pub struct BreakIfStatement {
724 pub attributes: Attributes,
726 pub expression: ExpressionNode,
727}
728
729#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
730#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
731#[derive(Clone, Debug, PartialEq)]
732pub struct ForStatement {
733 pub attributes: Attributes,
734 pub initializer: Option<StatementNode>,
735 pub condition: Option<ExpressionNode>,
736 pub update: Option<StatementNode>,
737 pub body: CompoundStatement,
738}
739
740#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
741#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
742#[derive(Clone, Debug, PartialEq)]
743pub struct WhileStatement {
744 pub attributes: Attributes,
745 pub condition: ExpressionNode,
746 pub body: CompoundStatement,
747}
748
749#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
750#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
751#[derive(Clone, Debug, PartialEq)]
752pub struct BreakStatement {
753 pub attributes: Attributes,
755}
756
757#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
758#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
759#[derive(Clone, Debug, PartialEq)]
760pub struct ContinueStatement {
761 pub attributes: Attributes,
763}
764
765#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
766#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
767#[derive(Clone, Debug, PartialEq)]
768pub struct ReturnStatement {
769 pub attributes: Attributes,
771 pub expression: Option<ExpressionNode>,
772}
773
774#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
775#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
776#[derive(Clone, Debug, PartialEq)]
777pub struct DiscardStatement {
778 pub attributes: Attributes,
780}
781
782#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
783#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
784#[derive(Clone, Debug, PartialEq)]
785pub struct FunctionCallStatement {
786 pub attributes: Attributes,
788 pub call: FunctionCall,
789}
790
791pub type ConstAssertStatement = ConstAssert;
792
793pub type DeclarationStatement = Declaration;