mago_syntax/ast/ast/loop/
for.rs1use serde::Serialize;
2use strum::Display;
3
4use mago_span::HasSpan;
5use mago_span::Span;
6
7use crate::ast::ast::expression::Expression;
8use crate::ast::ast::keyword::Keyword;
9use crate::ast::ast::statement::Statement;
10use crate::ast::ast::terminator::Terminator;
11use crate::ast::sequence::Sequence;
12use crate::ast::sequence::TokenSeparatedSequence;
13
14#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
26pub struct For<'arena> {
27 pub r#for: Keyword<'arena>,
28 pub left_parenthesis: Span,
29 pub initializations: TokenSeparatedSequence<'arena, Expression<'arena>>,
30 pub initializations_semicolon: Span,
31 pub conditions: TokenSeparatedSequence<'arena, Expression<'arena>>,
32 pub conditions_semicolon: Span,
33 pub increments: TokenSeparatedSequence<'arena, Expression<'arena>>,
34 pub right_parenthesis: Span,
35 pub body: ForBody<'arena>,
36}
37
38#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord, Display)]
40#[serde(tag = "type", content = "value")]
41#[repr(u8)]
42pub enum ForBody<'arena> {
43 Statement(&'arena Statement<'arena>),
44 ColonDelimited(ForColonDelimitedBody<'arena>),
45}
46
47#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
59pub struct ForColonDelimitedBody<'arena> {
60 pub colon: Span,
61 pub statements: Sequence<'arena, Statement<'arena>>,
62 pub end_for: Keyword<'arena>,
63 pub terminator: Terminator<'arena>,
64}
65
66impl<'arena> ForBody<'arena> {
67 #[inline]
68 #[must_use]
69 pub fn statements(&self) -> &[Statement<'arena>] {
70 match self {
71 ForBody::Statement(statement) => std::slice::from_ref(statement),
72 ForBody::ColonDelimited(body) => body.statements.as_slice(),
73 }
74 }
75}
76
77impl HasSpan for For<'_> {
78 fn span(&self) -> Span {
79 self.r#for.span().join(self.body.span())
80 }
81}
82
83impl HasSpan for ForBody<'_> {
84 fn span(&self) -> Span {
85 match self {
86 ForBody::Statement(statement) => statement.span(),
87 ForBody::ColonDelimited(body) => body.span(),
88 }
89 }
90}
91
92impl HasSpan for ForColonDelimitedBody<'_> {
93 fn span(&self) -> Span {
94 self.colon.join(self.terminator.span())
95 }
96}