Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- fn check_block(&mut self, type_environment: &'a mut TypeEnvironment<'_>, block: &Block, return_type: &Type) -> Result<()> {
- let mut type_env = TypeEnvironment::with_parent(type_environment);
- let location = &block.location;
- let searched_type = { &mut type_env }.search_type(location, "void")?.typ;
- if block.statements.len() == 0 {
- if type_env.unify(location, return_type, &searched_type).is_err() {
- return Err(SemanticError::new(location, SemanticErrorVariant::DeadCodeAfterReturnStatement));
- }
- }
- else {
- for (i, statement) in block.statements.iter().enumerate() {
- use StatementVariant::*;
- let location = &statement.location;
- match &statement.value {
- Return(expr) => {
- let typ = match expr {
- Some(e) => type_env.type_of_expression(e)?,
- None => type_env.search_type(location, "void")?.typ,
- };
- if i != block.statements.len() {
- return Err(SemanticError::new(location, SemanticErrorVariant::DeadCodeAfterReturnStatement));
- }
- type_env.unify(location, return_type, &typ)?;
- },
- Variable(variable) => {
- let variable_definition_type = { &mut type_env }.from(variable.clone().parsed_type)?;
- let variable_type = { &mut type_env }.type_of_expression(&variable.clone().expr)?;
- type_env.unify(location, &variable_definition_type, &variable_type)?;
- type_env.add_variable(location, &variable.name, variable_definition_type)?;
- let searched_type = type_env.search_type(location, "void")?.typ;
- if i == block.statements.len() - 1 {
- type_env.unify(
- location,
- return_type,
- &searched_type
- )?;
- }
- },
- Expression(method_call) => {
- let method_call_return_type = type_env.type_of_expression(method_call)?;
- let mut searched_type = type_env.search_type(location, "void")?.typ;
- type_env.unify(
- location,
- &searched_type,
- &method_call_return_type
- );
- if i == block.statements.len() - 1 {
- searched_type = type_env.search_type(location, "void")?.typ;
- type_env.unify(
- location,
- return_type,
- &searched_type
- );
- }
- },
- IfBlock {clauses, else_block} => {
- for (condition, then_block) in clauses {
- let condition_type = type_env.type_of_expression(condition)?;
- let searched_type = type_env.search_type(location, "bool")?.typ;
- type_env.unify(
- location,
- &searched_type,
- &condition_type,
- )?;
- self.check_block(&mut type_env, then_block, return_type)?;
- }
- self.check_block(&mut type_env, else_block, return_type)?;
- }
- }
- }
- }
- Ok(())
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement