Move hard_hint to scope
This commit is contained in:
		
							parent
							
								
									9b9fcd4ec4
								
							
						
					
					
						commit
						cdbc4593a8
					
				| @ -1,7 +1,7 @@ | ||||
| use std::{collections::HashMap, convert::Infallible, iter}; | ||||
| 
 | ||||
| /// This module contains code relevant to doing a type checking pass on the MIR.
 | ||||
| use crate::{mir::*, util::try_all}; | ||||
| use crate::{ast::Type, mir::*, util::try_all}; | ||||
| use TypeKind::*; | ||||
| use VagueType::*; | ||||
| 
 | ||||
| @ -113,6 +113,8 @@ impl State { | ||||
| pub struct Scope { | ||||
|     function_returns: TypeStorage<ScopeFunction>, | ||||
|     variables: TypeStorage<TypeKind>, | ||||
|     /// Hard Return type of this scope, if inside a function
 | ||||
|     return_type_hint: Option<TypeKind>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
| @ -126,6 +128,7 @@ impl Scope { | ||||
|         Scope { | ||||
|             function_returns: self.function_returns.clone(), | ||||
|             variables: self.variables.clone(), | ||||
|             return_type_hint: self.return_type_hint, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -176,7 +179,8 @@ impl FunctionDefinition { | ||||
|         let return_type = self.return_type.clone(); | ||||
|         let inferred = match &mut self.kind { | ||||
|             FunctionDefinitionKind::Local(block, _) => { | ||||
|                 block.typecheck(state, scope, Some(return_type), Some(return_type)) | ||||
|                 scope.return_type_hint = Some(self.return_type); | ||||
|                 block.typecheck(state, scope, Some(return_type)) | ||||
|             } | ||||
|             FunctionDefinitionKind::Extern => Ok(Vague(Unknown)), | ||||
|         }; | ||||
| @ -194,20 +198,14 @@ impl Block { | ||||
|         &mut self, | ||||
|         state: &mut State, | ||||
|         scope: &mut Scope, | ||||
|         soft_hint: Option<TypeKind>, | ||||
|         hard_hint: Option<TypeKind>, | ||||
|         hint_t: Option<TypeKind>, | ||||
|     ) -> Result<TypeKind, ErrorKind> { | ||||
|         let mut scope = scope.inner(); | ||||
| 
 | ||||
|         for statement in &mut self.statements { | ||||
|             match &mut statement.0 { | ||||
|                 StmtKind::Let(variable_reference, expression) => { | ||||
|                     let res = expression.typecheck( | ||||
|                         state, | ||||
|                         &mut scope, | ||||
|                         Some(variable_reference.0), | ||||
|                         hard_hint, | ||||
|                     ); | ||||
|                     let res = expression.typecheck(state, &mut scope, Some(variable_reference.0)); | ||||
| 
 | ||||
|                     // If expression resolution itself was erronous, resolve as
 | ||||
|                     // Unknown.
 | ||||
| @ -237,14 +235,18 @@ impl Block { | ||||
|                 } | ||||
|                 StmtKind::Import(_) => todo!(), | ||||
|                 StmtKind::Expression(expression) => { | ||||
|                     let res = expression.typecheck(state, &mut scope, soft_hint, hard_hint); | ||||
|                     let res = expression.typecheck(state, &mut scope, hint_t); | ||||
|                     state.ok(res, expression.1); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if let Some((_, expr)) = &mut self.return_expression { | ||||
|             let res = expr.typecheck(state, &mut scope, hard_hint, hard_hint); | ||||
|         if let Some((return_kind, expr)) = &mut self.return_expression { | ||||
|             let ret_hint_t = match return_kind { | ||||
|                 ReturnKind::Hard => scope.return_type_hint, | ||||
|                 ReturnKind::Soft => hint_t, | ||||
|             }; | ||||
|             let res = expr.typecheck(state, &mut scope, ret_hint_t); | ||||
|             Ok(state.or_else(res, Vague(Unknown), expr.1)) | ||||
|         } else { | ||||
|             Ok(Void) | ||||
| @ -257,8 +259,7 @@ impl Expression { | ||||
|         &mut self, | ||||
|         state: &mut State, | ||||
|         scope: &mut Scope, | ||||
|         soft_hint: Option<TypeKind>, | ||||
|         hard_hint: Option<TypeKind>, | ||||
|         hint_t: Option<TypeKind>, | ||||
|     ) -> Result<TypeKind, ErrorKind> { | ||||
|         match &mut self.0 { | ||||
|             ExprKind::Variable(var_ref) => { | ||||
| @ -282,15 +283,15 @@ impl Expression { | ||||
|                 Ok(var_ref.0) | ||||
|             } | ||||
|             ExprKind::Literal(literal) => { | ||||
|                 *literal = literal.try_coerce(soft_hint)?; | ||||
|                 *literal = literal.try_coerce(hint_t)?; | ||||
|                 Ok(literal.as_type()) | ||||
|             } | ||||
|             ExprKind::BinOp(op, lhs, rhs) => { | ||||
|                 // TODO make sure lhs and rhs can actually do this binary
 | ||||
|                 // operation once relevant
 | ||||
|                 let lhs_res = lhs.typecheck(state, scope, soft_hint, hard_hint); // TODO
 | ||||
|                 let lhs_res = lhs.typecheck(state, scope, None); // TODO
 | ||||
|                 let lhs_type = state.or_else(lhs_res, Vague(Unknown), lhs.1); | ||||
|                 let rhs_res = rhs.typecheck(state, scope, Some(lhs_type), hard_hint); // TODO
 | ||||
|                 let rhs_res = rhs.typecheck(state, scope, Some(lhs_type)); // TODO
 | ||||
|                 let rhs_type = state.or_else(rhs_res, Vague(Unknown), rhs.1); | ||||
|                 let res = lhs_type.binop_type(&op, &rhs_type)?; | ||||
|                 Ok(res) | ||||
| @ -312,8 +313,7 @@ impl Expression { | ||||
|                     for (param, true_param_t) in | ||||
|                         function_call.parameters.iter_mut().zip(true_params_iter) | ||||
|                     { | ||||
|                         let param_res = | ||||
|                             param.typecheck(state, scope, Some(true_param_t), hard_hint); | ||||
|                         let param_res = param.typecheck(state, scope, Some(true_param_t)); | ||||
|                         let param_t = state.or_else(param_res, Vague(Unknown), param.1); | ||||
|                         state.ok(param_t.collapse_into(&true_param_t), param.1); | ||||
|                     } | ||||
| @ -330,21 +330,21 @@ impl Expression { | ||||
|             } | ||||
|             ExprKind::If(IfExpression(cond, lhs, rhs)) => { | ||||
|                 // TODO make sure cond_res is Boolean here
 | ||||
|                 let cond_res = cond.typecheck(state, scope, Some(Bool), hard_hint); | ||||
|                 let cond_res = cond.typecheck(state, scope, Some(Bool)); | ||||
|                 let cond_t = state.or_else(cond_res, Vague(Unknown), cond.1); | ||||
|                 state.ok(cond_t.collapse_into(&Bool), cond.1); | ||||
| 
 | ||||
|                 let lhs_res = lhs.typecheck(state, scope, soft_hint, hard_hint); | ||||
|                 let lhs_res = lhs.typecheck(state, scope, hint_t); | ||||
|                 let lhs_type = state.or_else(lhs_res, Vague(Unknown), lhs.meta); | ||||
|                 let rhs_type = if let Some(rhs) = rhs { | ||||
|                     let res = rhs.typecheck(state, scope, soft_hint, hard_hint); | ||||
|                     let res = rhs.typecheck(state, scope, hint_t); | ||||
|                     state.or_else(res, Vague(Unknown), rhs.meta) | ||||
|                 } else { | ||||
|                     Vague(Unknown) | ||||
|                 }; | ||||
|                 lhs_type.collapse_into(&rhs_type) | ||||
|             } | ||||
|             ExprKind::Block(block) => block.typecheck(state, scope, soft_hint, hard_hint), | ||||
|             ExprKind::Block(block) => block.typecheck(state, scope, hint_t), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user