Skip to main content

oak_c/ast/
statement_nodes.rs

1use super::*;
2
3/// Statement.
4#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5#[derive(Debug, Clone, PartialEq)]
6pub enum Statement {
7    /// Labeled statement.
8    Labeled(LabeledStatement),
9    /// Compound statement.
10    Compound(CompoundStatement),
11    /// Expression statement.
12    Expression(ExpressionStatement),
13    /// Selection statement (if, switch).
14    Selection(SelectionStatement),
15    /// Iteration statement (while, do, for).
16    Iteration(IterationStatement),
17    /// Jump statement (goto, continue, break, return).
18    Jump(JumpStatement),
19}
20
21impl Statement {
22    /// Returns the source span of the statement.
23    pub fn span(&self) -> core::range::Range<usize> {
24        match self {
25            Self::Labeled(n) => n.span(),
26            Self::Compound(n) => n.span.clone(),
27            Self::Expression(n) => n.span.clone(),
28            Self::Selection(n) => n.span(),
29            Self::Iteration(n) => n.span(),
30            Self::Jump(n) => n.span(),
31        }
32    }
33}
34
35/// Labeled statement.
36#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
37#[derive(Debug, Clone, PartialEq)]
38pub enum LabeledStatement {
39    /// `identifier: statement`
40    Label {
41        /// Label name.
42        identifier: String,
43        /// Labeled statement.
44        statement: Box<Statement>,
45        /// Source span.
46        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
47        span: core::range::Range<usize>,
48    },
49    /// `case constant-expression: statement`
50    Case {
51        /// Case expression.
52        constant_expression: Expression,
53        /// Statement.
54        statement: Box<Statement>,
55        /// Source span.
56        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
57        span: core::range::Range<usize>,
58    },
59    /// `default: statement`
60    Default {
61        /// Statement.
62        statement: Box<Statement>,
63        /// Source span.
64        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
65        span: core::range::Range<usize>,
66    },
67}
68
69impl LabeledStatement {
70    /// Returns the source span of the labeled statement.
71    pub fn span(&self) -> core::range::Range<usize> {
72        match self {
73            Self::Label { span, .. } => span.clone(),
74            Self::Case { span, .. } => span.clone(),
75            Self::Default { span, .. } => span.clone(),
76        }
77    }
78}
79
80/// Compound statement (block).
81#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
82#[derive(Debug, Clone, PartialEq)]
83pub struct CompoundStatement {
84    /// List of block items (declarations or statements).
85    pub block_items: Vec<BlockItem>,
86    /// Source span.
87    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
88    pub span: core::range::Range<usize>,
89}
90
91/// Block item.
92#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
93#[derive(Debug, Clone, PartialEq)]
94pub enum BlockItem {
95    /// Declaration.
96    Declaration(Declaration),
97    /// Statement.
98    Statement(Statement),
99}
100
101impl BlockItem {
102    /// Returns the source span of the block item.
103    pub fn span(&self) -> core::range::Range<usize> {
104        match self {
105            Self::Declaration(n) => n.span.clone(),
106            Self::Statement(n) => n.span(),
107        }
108    }
109}
110
111/// Expression statement.
112#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
113#[derive(Debug, Clone, PartialEq)]
114pub struct ExpressionStatement {
115    /// Optional expression.
116    pub expression: Option<Expression>,
117    /// Source span.
118    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
119    pub span: core::range::Range<usize>,
120}
121
122/// Selection statement.
123#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
124#[derive(Debug, Clone, PartialEq)]
125pub enum SelectionStatement {
126    /// `if (condition) then_statement else else_statement?`
127    If {
128        /// Condition.
129        condition: Expression,
130        /// Then branch.
131        then_statement: Box<Statement>,
132        /// Optional else branch.
133        else_statement: Option<Box<Statement>>,
134        /// Source span.
135        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
136        span: core::range::Range<usize>,
137    },
138    /// `switch (expression) statement`
139    Switch {
140        /// Switch expression.
141        expression: Expression,
142        /// Switch body.
143        statement: Box<Statement>,
144        /// Source span.
145        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
146        span: core::range::Range<usize>,
147    },
148}
149
150impl SelectionStatement {
151    /// Returns the source span of the selection statement.
152    pub fn span(&self) -> core::range::Range<usize> {
153        match self {
154            Self::If { span, .. } => span.clone(),
155            Self::Switch { span, .. } => span.clone(),
156        }
157    }
158}
159
160/// Iteration statement.
161#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
162#[derive(Debug, Clone, PartialEq)]
163pub enum IterationStatement {
164    /// `while (condition) statement`
165    While {
166        /// Condition.
167        condition: Expression,
168        /// Loop body.
169        statement: Box<Statement>,
170        /// Source span.
171        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
172        span: core::range::Range<usize>,
173    },
174    /// `do statement while (condition);`
175    DoWhile {
176        /// Loop body.
177        statement: Box<Statement>,
178        /// Condition.
179        condition: Expression,
180        /// Source span.
181        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
182        span: core::range::Range<usize>,
183    },
184    /// `for (init; condition; update) statement`
185    For {
186        /// Optional initializer expression.
187        init: Option<Expression>,
188        /// Optional condition expression.
189        condition: Option<Expression>,
190        /// Optional update expression.
191        update: Option<Expression>,
192        /// Loop body.
193        statement: Box<Statement>,
194        /// Source span.
195        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
196        span: core::range::Range<usize>,
197    },
198}
199
200impl IterationStatement {
201    /// Returns the source span of the iteration statement.
202    pub fn span(&self) -> core::range::Range<usize> {
203        match self {
204            Self::While { span, .. } => span.clone(),
205            Self::DoWhile { span, .. } => span.clone(),
206            Self::For { span, .. } => span.clone(),
207        }
208    }
209}
210
211/// Jump statement.
212#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
213#[derive(Debug, Clone, PartialEq)]
214pub enum JumpStatement {
215    /// `goto identifier;`
216    Goto(String, #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))] core::range::Range<usize>),
217    /// `continue;`
218    Continue(#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))] core::range::Range<usize>),
219    /// `break;`
220    Break(#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))] core::range::Range<usize>),
221    /// `return expression?;`
222    Return(Option<Expression>, #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))] core::range::Range<usize>),
223}
224
225impl JumpStatement {
226    /// Returns the source span of the jump statement.
227    pub fn span(&self) -> core::range::Range<usize> {
228        match self {
229            Self::Goto(_, span) => span.clone(),
230            Self::Continue(span) => span.clone(),
231            Self::Break(span) => span.clone(),
232            Self::Return(_, span) => span.clone(),
233        }
234    }
235}