diff --git a/src/abstract_tree/block.rs b/src/abstract_tree/block.rs index 28d9e13..b588258 100644 --- a/src/abstract_tree/block.rs +++ b/src/abstract_tree/block.rs @@ -19,14 +19,54 @@ impl<'src> Block<'src> { impl<'src> AbstractTree for Block<'src> { fn expected_type(&self, _context: &Context) -> Result { - todo!() + let final_statement = self.statements.last().unwrap(); + + final_statement.expected_type(_context) } fn validate(&self, _context: &Context) -> Result<(), ValidationError> { - todo!() + for statement in &self.statements { + statement.validate(_context)?; + } + + Ok(()) } - fn run(self, _: &Context) -> Result { - todo!() + fn run(self, _context: &Context) -> Result { + let mut previous = Value::none(); + + for statement in self.statements { + previous = statement.run(_context)?; + } + + Ok(previous) + } +} + +#[cfg(test)] +mod tests { + use crate::abstract_tree::{Expression, ValueNode}; + + use super::*; + + #[test] + fn run_returns_value_of_final_statement() { + let block = Block::new(vec![ + Statement::Expression(Expression::Value(ValueNode::Integer(1))), + Statement::Expression(Expression::Value(ValueNode::Integer(2))), + Statement::Expression(Expression::Value(ValueNode::Integer(42))), + ]); + + assert_eq!(block.run(&Context::new()), Ok(Value::integer(42))) + } + + #[test] + fn expected_type_returns_type_of_final_statement() { + let block = Block::new(vec![ + Statement::Expression(Expression::Value(ValueNode::String("42"))), + Statement::Expression(Expression::Value(ValueNode::Integer(42))), + ]); + + assert_eq!(block.expected_type(&Context::new()), Ok(Type::Integer)) } } diff --git a/src/abstract_tree/expression.rs b/src/abstract_tree/expression.rs index 386e6c0..868af79 100644 --- a/src/abstract_tree/expression.rs +++ b/src/abstract_tree/expression.rs @@ -15,7 +15,11 @@ pub enum Expression<'src> { impl<'src> AbstractTree for Expression<'src> { fn expected_type(&self, _context: &Context) -> Result { - todo!() + match self { + Expression::Identifier(identifier) => identifier.expected_type(_context), + Expression::Logic(logic) => logic.expected_type(_context), + Expression::Value(value_node) => value_node.expected_type(_context), + } } fn validate(&self, _context: &Context) -> Result<(), ValidationError> { diff --git a/src/abstract_tree/statement.rs b/src/abstract_tree/statement.rs index 017cb65..8363812 100644 --- a/src/abstract_tree/statement.rs +++ b/src/abstract_tree/statement.rs @@ -15,7 +15,12 @@ pub enum Statement<'src> { impl<'src> AbstractTree for Statement<'src> { fn expected_type(&self, _context: &Context) -> Result { - todo!() + match self { + Statement::Assignment(assignment) => assignment.expected_type(_context), + Statement::Block(block) => block.expected_type(_context), + Statement::Expression(expression) => expression.expected_type(_context), + Statement::Loop(r#loop) => r#loop.expected_type(_context), + } } fn validate(&self, _context: &Context) -> Result<(), ValidationError> {