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