use super::*;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, PartialEq)]
pub enum Statement {
Labeled(LabeledStatement),
Compound(CompoundStatement),
Expression(ExpressionStatement),
Selection(SelectionStatement),
Iteration(IterationStatement),
Jump(JumpStatement),
}
impl Statement {
pub fn span(&self) -> core::range::Range<usize> {
match self {
Self::Labeled(n) => n.span(),
Self::Compound(n) => n.span.clone(),
Self::Expression(n) => n.span.clone(),
Self::Selection(n) => n.span(),
Self::Iteration(n) => n.span(),
Self::Jump(n) => n.span(),
}
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, PartialEq)]
pub enum LabeledStatement {
Label {
identifier: String,
statement: Box<Statement>,
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
span: core::range::Range<usize>,
},
Case {
constant_expression: Expression,
statement: Box<Statement>,
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
span: core::range::Range<usize>,
},
Default {
statement: Box<Statement>,
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
span: core::range::Range<usize>,
},
}
impl LabeledStatement {
pub fn span(&self) -> core::range::Range<usize> {
match self {
Self::Label { span, .. } => span.clone(),
Self::Case { span, .. } => span.clone(),
Self::Default { span, .. } => span.clone(),
}
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, PartialEq)]
pub struct CompoundStatement {
pub block_items: Vec<BlockItem>,
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: core::range::Range<usize>,
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, PartialEq)]
pub enum BlockItem {
Declaration(Declaration),
Statement(Statement),
}
impl BlockItem {
pub fn span(&self) -> core::range::Range<usize> {
match self {
Self::Declaration(n) => n.span.clone(),
Self::Statement(n) => n.span(),
}
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, PartialEq)]
pub struct ExpressionStatement {
pub expression: Option<Expression>,
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: core::range::Range<usize>,
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, PartialEq)]
pub enum SelectionStatement {
If {
condition: Expression,
then_statement: Box<Statement>,
else_statement: Option<Box<Statement>>,
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
span: core::range::Range<usize>,
},
Switch {
expression: Expression,
statement: Box<Statement>,
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
span: core::range::Range<usize>,
},
}
impl SelectionStatement {
pub fn span(&self) -> core::range::Range<usize> {
match self {
Self::If { span, .. } => span.clone(),
Self::Switch { span, .. } => span.clone(),
}
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, PartialEq)]
pub enum IterationStatement {
While {
condition: Expression,
statement: Box<Statement>,
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
span: core::range::Range<usize>,
},
DoWhile {
statement: Box<Statement>,
condition: Expression,
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
span: core::range::Range<usize>,
},
For {
init: Option<Expression>,
condition: Option<Expression>,
update: Option<Expression>,
statement: Box<Statement>,
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
span: core::range::Range<usize>,
},
}
impl IterationStatement {
pub fn span(&self) -> core::range::Range<usize> {
match self {
Self::While { span, .. } => span.clone(),
Self::DoWhile { span, .. } => span.clone(),
Self::For { span, .. } => span.clone(),
}
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, PartialEq)]
pub enum JumpStatement {
Goto(String, #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))] core::range::Range<usize>),
Continue(#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))] core::range::Range<usize>),
Break(#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))] core::range::Range<usize>),
Return(Option<Expression>, #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))] core::range::Range<usize>),
}
impl JumpStatement {
pub fn span(&self) -> core::range::Range<usize> {
match self {
Self::Goto(_, span) => span.clone(),
Self::Continue(span) => span.clone(),
Self::Break(span) => span.clone(),
Self::Return(_, span) => span.clone(),
}
}
}