diff --git a/src/abstract_tree/function_call.rs b/src/abstract_tree/function_call.rs index af16420..548421f 100644 --- a/src/abstract_tree/function_call.rs +++ b/src/abstract_tree/function_call.rs @@ -37,18 +37,18 @@ impl AbstractTree for FunctionCall { } } - fn run(self, _context: &Context) -> Result { - let value = self.function.run(_context)?.as_value()?; + fn run(self, context: &Context) -> Result { + let value = self.function.run(context)?.as_value()?; let function = value.as_function()?; let mut arguments = Vec::with_capacity(self.arguments.len()); for expression in self.arguments { - let value = expression.run(_context)?.as_value()?; + let value = expression.run(context)?.as_value()?; arguments.push(value); } - let function_context = Context::new(); + let function_context = Context::with_data_from(context)?; function.call(arguments, function_context) } diff --git a/src/abstract_tree/if_else.rs b/src/abstract_tree/if_else.rs index 45921a2..89d0320 100644 --- a/src/abstract_tree/if_else.rs +++ b/src/abstract_tree/if_else.rs @@ -24,11 +24,18 @@ impl IfElse { impl AbstractTree for IfElse { fn expected_type(&self, _context: &Context) -> Result { - Ok(Type::None) + self.if_block.expected_type(_context) } - fn validate(&self, _context: &Context) -> Result<(), ValidationError> { - if let Type::Boolean = self.if_expression.expected_type(_context)? { + fn validate(&self, context: &Context) -> Result<(), ValidationError> { + if let Type::Boolean = self.if_expression.expected_type(context)? { + if let Some(else_block) = &self.else_block { + let expected = self.if_block.expected_type(context)?; + let actual = else_block.expected_type(context)?; + + expected.check(&actual)?; + } + Ok(()) } else { Err(ValidationError::ExpectedBoolean) diff --git a/src/abstract_tree/value_node.rs b/src/abstract_tree/value_node.rs index 0dd2043..acd9656 100644 --- a/src/abstract_tree/value_node.rs +++ b/src/abstract_tree/value_node.rs @@ -78,7 +78,7 @@ impl AbstractTree for ValueNode { body, } = self { - let function_context = Context::new(); + let function_context = Context::with_types_from(context)?; for (identifier, r#type) in parameters { function_context.set_type(identifier.clone(), r#type.clone())?; diff --git a/src/context.rs b/src/context.rs index dd164f2..c8f0a25 100644 --- a/src/context.rs +++ b/src/context.rs @@ -33,6 +33,28 @@ impl Context { } } + pub fn with_types_from(other: &Context) -> Result { + let mut new_data = BTreeMap::new(); + + for (identifier, value_data) in other.inner.read()?.iter() { + if let ValueData::Type(_) = value_data { + new_data.insert(identifier.clone(), value_data.clone()); + } + } + + Ok(Self::with_data(new_data)) + } + + pub fn with_data_from(other: &Context) -> Result { + let mut new_data = BTreeMap::new(); + + for (identifier, value_data) in other.inner.read()?.iter() { + new_data.insert(identifier.clone(), value_data.clone()); + } + + Ok(Self::with_data(new_data)) + } + pub fn get_data( &self, identifier: &Identifier,