use serde::Serialize; use super::*; #[derive(Debug, Clone, Serialize, Default)] pub struct Block( pub Vec>, pub Option>, ); #[derive(Debug, Clone, Serialize)] pub enum StatementBody { Statement(Expression), Expression(Expression), } #[derive(Debug, Clone, Serialize)] pub enum Statement { Block(Block), If { initial: StatementBranch, else_if: Vec, else_branch: Option, }, Loop(StatementBody), While(StatementBranch), CStyleFor { init: Expression, condition: Expression, update: Expression, body: StatementBody, }, For { mutable: bool, pattern: Pattern, iterator: Expression, body: StatementBody, }, Match(Expression, Vec<(Vec, Expression)>), VarDecl(VarDeclStmt), Return(Option), Break, Continue, } #[derive(Debug, Clone, Serialize)] pub struct VarDecl { pub mutable: bool, pub name: Pattern, pub type_: Option, } #[derive(Debug, Clone, Serialize)] pub struct VarDeclStmt { pub decl: VarDecl, pub init: Option, } #[derive(Debug, Clone, Serialize)] pub struct StatementBranch { pub condition: Expression, pub body: Box, } impl Statement { pub fn is_soft_return(&self) -> bool { match self { Self::Block(_) | Self::Match(_, _) => true, Self::While(branch) => branch.body.is_soft_return(), Self::For { body, .. } | Self::Loop(body) | Self::CStyleFor { body, .. } => { body.is_soft_return() } Self::If { initial, else_if, else_branch, } => { else_branch .as_ref() .map(|v| v.is_soft_return()) .unwrap_or_default() || else_if .last() .map(|b| b.body.is_soft_return()) .unwrap_or_default() || initial.body.is_soft_return() } _ => false, } } } impl StatementBody { pub fn is_soft_return(&self) -> bool { match self { Self::Expression(_) => true, _ => false, } } }