use crate::ast::node::expression::Expression; use crate::ast::node::names::Identifier; use crate::ast::node::type_use::TypeUse; #[derive(Debug)] pub struct BlockStatement { statements: Vec>, expression: Option>, } impl BlockStatement { pub fn new(statements: Vec>, expression: Option>) -> Self { Self { statements, expression, } } pub fn statements(&self) -> Vec<&Statement> { self.statements.iter().map(AsRef::as_ref).collect() } pub fn statements_mut(&mut self) -> Vec<&mut Statement> { self.statements.iter_mut().map(AsMut::as_mut).collect() } pub fn expression(&self) -> Option<&Expression> { if let Some(ref expression) = self.expression { Some(expression.as_ref()) } else { None } } pub fn expression_mut(&mut self) -> Option<&mut Expression> { if let Some(ref mut expression) = self.expression { Some(expression.as_mut()) } else { None } } } #[derive(Debug)] pub enum Statement { BlockStatement(Box), VariableDeclarationStatement(Box), AssignStatement(Box), CallStatement(Box), ReturnStatement(Box), IfStatement(Box), IfElseStatement(Box), WhileStatement(Box), ForStatement(Box), } #[derive(Debug)] pub struct VariableDeclarationStatement { is_mutable: bool, identifier: Box, declared_type: Option>, initializer: Option>, } impl VariableDeclarationStatement { pub fn new( is_mutable: bool, identifier: Box, declared_type: Option>, initializer: Option>, ) -> Self { Self { is_mutable, identifier, declared_type, initializer, } } pub fn is_mutable(&self) -> bool { self.is_mutable } pub fn identifier(&self) -> &Identifier { &self.identifier } pub fn identifier_mut(&mut self) -> &mut Identifier { &mut self.identifier } pub fn declared_type(&self) -> Option<&TypeUse> { if let Some(type_use) = &self.declared_type { Some(type_use.as_ref()) } else { None } } pub fn declared_type_mut(&mut self) -> Option<&mut TypeUse> { if let Some(type_use) = &mut self.declared_type { Some(type_use.as_mut()) } else { None } } pub fn initializer(&self) -> Option<&Expression> { if let Some(initializer) = &self.initializer { Some(initializer.as_ref()) } else { None } } pub fn initializer_mut(&mut self) -> Option<&mut Expression> { if let Some(initializer) = &mut self.initializer { Some(initializer.as_mut()) } else { None } } } #[derive(Debug)] pub struct AssignStatement { lhs: Box, rhs: Box, } impl AssignStatement { pub fn new(lhs: Box, rhs: Box) -> Self { Self { lhs, rhs } } pub fn lhs(&self) -> &Expression { &self.lhs } pub fn lhs_mut(&mut self) -> &mut Expression { &mut self.lhs } pub fn rhs(&self) -> &Expression { &self.rhs } pub fn rhs_mut(&mut self) -> &mut Expression { &mut self.rhs } } #[derive(Debug)] pub struct CallStatement(Box); impl CallStatement { pub fn new(call_expression: Box) -> Self { Self(call_expression) } pub fn expression(&self) -> &Expression { &self.0 } pub fn expression_mut(&mut self) -> &mut Expression { &mut self.0 } } #[derive(Debug)] pub struct ReturnStatement(Option>); impl ReturnStatement { pub fn new(expression: Option>) -> Self { Self(expression) } pub fn expression(&self) -> Option<&Expression> { if let Some(expression) = &self.0 { Some(expression.as_ref()) } else { None } } pub fn expression_mut(&mut self) -> Option<&mut Expression> { if let Some(expression) = &mut self.0 { Some(expression.as_mut()) } else { None } } } #[derive(Debug)] pub struct IfStatement { condition: Box, then_block: Box, } impl IfStatement { pub fn new(condition: Box, then_block: Box) -> Self { Self { condition, then_block, } } pub fn condition(&self) -> &Expression { &self.condition } pub fn condition_mut(&mut self) -> &mut Expression { &mut self.condition } pub fn then_block(&self) -> &BlockStatement { &self.then_block } pub fn then_block_mut(&mut self) -> &mut BlockStatement { &mut self.then_block } } #[derive(Debug)] pub struct IfElseStatement { if_statement: Box, else_ifs: Box, else_block: Option>, } impl IfElseStatement { pub fn new( if_statement: Box, else_ifs: Box, else_block: Option>, ) -> Self { Self { if_statement, else_ifs, else_block, } } pub fn if_statement(&self) -> &IfStatement { &self.if_statement } pub fn if_statement_mut(&mut self) -> &mut IfStatement { &mut self.if_statement } pub fn else_ifs(&self) -> &ElseIfs { &self.else_ifs } pub fn else_ifs_mut(&mut self) -> &mut ElseIfs { &mut self.else_ifs } pub fn else_block(&self) -> Option<&ElseBlock> { if let Some(else_block) = &self.else_block { Some(else_block.as_ref()) } else { None } } pub fn else_block_mut(&mut self) -> Option<&mut ElseBlock> { if let Some(else_block) = &mut self.else_block { Some(else_block.as_mut()) } else { None } } } #[derive(Debug, Default)] pub struct ElseIfs(Vec>); impl ElseIfs { pub fn new(if_statements: Vec>) -> Self { Self(if_statements) } pub fn if_statements(&self) -> Vec<&IfStatement> { self.0.iter().map(Box::as_ref).collect() } pub fn if_statements_mut(&mut self) -> Vec<&mut IfStatement> { self.0.iter_mut().map(Box::as_mut).collect() } } #[derive(Debug)] pub struct ElseBlock(Box); impl ElseBlock { pub fn new(block: Box) -> Self { Self(block) } pub fn block_statement(&self) -> &BlockStatement { &self.0 } pub fn block_statement_mut(&mut self) -> &mut BlockStatement { &mut self.0 } } #[derive(Debug)] pub struct WhileStatement { condition: Box, body: Box, } impl WhileStatement { pub fn new(condition: Box, body: Box) -> Self { Self { condition, body } } pub fn condition(&self) -> &Expression { &self.condition } pub fn condition_mut(&mut self) -> &mut Expression { &mut self.condition } pub fn body(&self) -> &BlockStatement { &self.body } pub fn body_mut(&mut self) -> &mut BlockStatement { &mut self.body } } #[derive(Debug)] pub struct ForStatement { variable: Box, iterator: Box, body: Box, } impl ForStatement { pub fn new( variable: Box, iterator: Box, body: Box, ) -> Self { Self { variable, iterator, body, } } pub fn variable(&self) -> &Identifier { &self.variable } pub fn variable_mut(&mut self) -> &mut Identifier { &mut self.variable } pub fn iterator(&self) -> &Expression { &self.iterator } pub fn iterator_mut(&mut self) -> &mut Expression { &mut self.iterator } pub fn body(&self) -> &BlockStatement { &self.body } pub fn body_mut(&mut self) -> &mut BlockStatement { &mut self.body } }