Advertisement
HTG_YT

check_block.rs

Sep 8th, 2020 (edited)
1,810
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 3.89 KB | None | 0 0
  1.     fn check_block(&mut self, type_environment: &'a mut TypeEnvironment<'_>, block: &Block, return_type: &Type) -> Result<()> {
  2.         let mut type_env = TypeEnvironment::with_parent(type_environment);
  3.         let location = &block.location;
  4.  
  5.         let searched_type = { &mut type_env }.search_type(location, "void")?.typ;
  6.  
  7.         if block.statements.len() == 0 {
  8.             if type_env.unify(location, return_type, &searched_type).is_err() {
  9.                 return Err(SemanticError::new(location, SemanticErrorVariant::DeadCodeAfterReturnStatement));
  10.             }
  11.         }
  12.         else {
  13.             for (i, statement) in block.statements.iter().enumerate() {
  14.                 use StatementVariant::*;
  15.  
  16.                 let location = &statement.location;
  17.  
  18.                 match &statement.value {
  19.                     Return(expr) => {
  20.                         let typ = match expr {
  21.                             Some(e) => type_env.type_of_expression(e)?,
  22.                             None => type_env.search_type(location, "void")?.typ,
  23.                         };
  24.  
  25.                         if i != block.statements.len() {
  26.                             return Err(SemanticError::new(location, SemanticErrorVariant::DeadCodeAfterReturnStatement));
  27.                         }
  28.  
  29.                         type_env.unify(location, return_type, &typ)?;
  30.                     },
  31.                     Variable(variable) => {
  32.                         let variable_definition_type = { &mut type_env }.from(variable.clone().parsed_type)?;
  33.                         let variable_type = { &mut type_env }.type_of_expression(&variable.clone().expr)?;
  34.  
  35.                         type_env.unify(location, &variable_definition_type, &variable_type)?;
  36.                         type_env.add_variable(location, &variable.name, variable_definition_type)?;
  37.  
  38.                         let searched_type = type_env.search_type(location, "void")?.typ;
  39.  
  40.                         if i == block.statements.len() - 1 {
  41.                             type_env.unify(
  42.                                 location,
  43.                                 return_type,
  44.                                 &searched_type
  45.                             )?;
  46.                         }
  47.                     },
  48.                     Expression(method_call) => {
  49.                         let method_call_return_type = type_env.type_of_expression(method_call)?;
  50.  
  51.                         let mut searched_type = type_env.search_type(location, "void")?.typ;
  52.  
  53.                         type_env.unify(
  54.                             location,
  55.                             &searched_type,
  56.                             &method_call_return_type
  57.                         );
  58.  
  59.                         if i == block.statements.len() - 1 {
  60.                             searched_type = type_env.search_type(location, "void")?.typ;
  61.  
  62.                             type_env.unify(
  63.                                 location,
  64.                                 return_type,
  65.                                 &searched_type
  66.                             );
  67.                         }
  68.                     },
  69.                     IfBlock {clauses, else_block} => {
  70.                         for (condition, then_block) in clauses {
  71.                             let condition_type = type_env.type_of_expression(condition)?;
  72.                             let searched_type = type_env.search_type(location, "bool")?.typ;
  73.  
  74.                             type_env.unify(
  75.                                 location,
  76.                                 &searched_type,
  77.                                 &condition_type,
  78.                             )?;
  79.  
  80.                             self.check_block(&mut type_env, then_block, return_type)?;
  81.                         }
  82.  
  83.                         self.check_block(&mut type_env, else_block, return_type)?;
  84.                     }
  85.                 }
  86.             }
  87.         }
  88.  
  89.         Ok(())
  90.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement