todo: typechecking, then ensure placeness and IR still work as expected
This commit is contained in:
		
							parent
							
								
									4c7813aa98
								
							
						
					
					
						commit
						aeab786fe3
					
				|  | @ -10,6 +10,7 @@ use super::{ | |||
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||||
| enum ErrorKind { | ||||
|     MismatchingTypes, | ||||
|     DerefNonPointer, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||||
|  | @ -247,6 +248,15 @@ impl<'a> AstVisitorTrait<&'a mut Ast> for TypeChecker<'_> { | |||
|         Ok(Some(ty)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_interned_type_impl( | ||||
|         &mut self, | ||||
|         ast: &'a mut Ast, | ||||
|         idx: Index, | ||||
|         intern: intern::Index, | ||||
|     ) -> Result<Self::Value, Self::Error> { | ||||
|         Ok(Some(intern)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_any( | ||||
|         &mut self, | ||||
|         ast: &'a mut Ast, | ||||
|  | @ -257,7 +267,7 @@ impl<'a> AstVisitorTrait<&'a mut Ast> for TypeChecker<'_> { | |||
|         let _ty = match tag { | ||||
|             Tag::Root => unreachable!(), | ||||
|             Tag::InternedType => Some(data.as_intern()), | ||||
|             Tag::File => self.visit_children(ast, idx)?, | ||||
|             Tag::File => self.visit_file(ast, idx)?, | ||||
|             Tag::ArrayType => self.visit_array_type(ast, idx)?, | ||||
|             Tag::PointerType => self.visit_pointer_type(ast, idx)?, | ||||
|             Tag::TypeDeclRef => self.visit_type_decl_ref(ast, idx)?, | ||||
|  | @ -265,18 +275,13 @@ impl<'a> AstVisitorTrait<&'a mut Ast> for TypeChecker<'_> { | |||
|             Tag::FunctionProto => self.visit_function_proto(ast, idx)?, | ||||
|             Tag::Parameter => self.visit_parameter(ast, idx)?, | ||||
|             Tag::StructDecl => self.visit_struct_decl(ast, idx)?, | ||||
|             Tag::StructDeclInterned => { | ||||
|                 let (_, ty) = data.as_two_interns(); | ||||
| 
 | ||||
|                 Some(ty) | ||||
|             } | ||||
|             Tag::StructDeclInterned => self.visit_struct_decl_interned(ast, idx)?, | ||||
|             Tag::FunctionDecl => self.visit_function_decl(ast, idx)?, | ||||
|             Tag::ParameterList => todo!(), | ||||
|             Tag::Block => todo!(), | ||||
|             Tag::BlockTrailingExpr => todo!(), | ||||
|             Tag::Constant => todo!(), | ||||
|             Tag::ExprStmt => todo!(), | ||||
|             Tag::ReturnStmt => todo!(), | ||||
|             Tag::Block | Tag::BlockTrailingExpr => self.visit_block(ast, idx)?, | ||||
|             Tag::Constant => self.visit_constant(ast, idx)?, | ||||
|             Tag::ExprStmt => self.visit_expr_stmt(ast, idx)?, | ||||
|             Tag::ReturnStmt => self.visit_return_stmt(ast, idx)?, | ||||
|             Tag::ReturnExprStmt => todo!(), | ||||
|             Tag::VarDecl => todo!(), | ||||
|             Tag::MutVarDecl => todo!(), | ||||
|  | @ -292,39 +297,203 @@ impl<'a> AstVisitorTrait<&'a mut Ast> for TypeChecker<'_> { | |||
|             Tag::ArgumentList => todo!(), | ||||
|             Tag::Argument => todo!(), | ||||
|             Tag::NamedArgument => todo!(), | ||||
|             Tag::ExplicitCast => todo!(), | ||||
|             Tag::Deref => todo!(), | ||||
|             Tag::AddressOf => todo!(), | ||||
|             Tag::Not => todo!(), | ||||
|             Tag::Negate => todo!(), | ||||
|             Tag::PlaceToValueConversion => todo!(), | ||||
|             Tag::ValueToPlaceConversion => todo!(), | ||||
|             Tag::Or => todo!(), | ||||
|             Tag::And => todo!(), | ||||
|             Tag::BitOr => todo!(), | ||||
|             Tag::BitXOr => todo!(), | ||||
|             Tag::BitAnd => todo!(), | ||||
|             Tag::Eq => todo!(), | ||||
|             Tag::NEq => todo!(), | ||||
|             Tag::Lt => todo!(), | ||||
|             Tag::Gt => todo!(), | ||||
|             Tag::Le => todo!(), | ||||
|             Tag::Ge => todo!(), | ||||
|             Tag::Shl => todo!(), | ||||
|             Tag::Shr => todo!(), | ||||
|             Tag::Add => todo!(), | ||||
|             Tag::Sub => todo!(), | ||||
|             Tag::Mul => todo!(), | ||||
|             Tag::Div => todo!(), | ||||
|             Tag::Rem => todo!(), | ||||
|             Tag::Assign => todo!(), | ||||
|             Tag::SubscriptExpr => todo!(), | ||||
|             Tag::IfExpr => todo!(), | ||||
|             Tag::IfElseExpr => todo!(), | ||||
|             Tag::ExplicitCast => self.visit_explicit_cast(ast, idx)?, | ||||
|             Tag::Deref => self.visit_deref(ast, idx)?, | ||||
|             Tag::AddressOf => self.visit_address_of(ast, idx)?, | ||||
|             Tag::Not | Tag::Negate => { | ||||
|                 let ty = self.visit_any(ast, data.as_index())?; | ||||
|                 ty | ||||
|             } | ||||
|             Tag::PlaceToValueConversion => self.visit_place_to_value_conversion(ast, idx)?, | ||||
|             Tag::ValueToPlaceConversion => self.visit_value_to_place_conversion(ast, idx)?, | ||||
|             Tag::Or | ||||
|             | Tag::And | ||||
|             | Tag::BitOr | ||||
|             | Tag::BitXOr | ||||
|             | Tag::BitAnd | ||||
|             | Tag::Eq | ||||
|             | Tag::NEq | ||||
|             | Tag::Lt | ||||
|             | Tag::Gt | ||||
|             | Tag::Le | ||||
|             | Tag::Ge | ||||
|             | Tag::Shl | ||||
|             | Tag::Shr | ||||
|             | Tag::Add | ||||
|             | Tag::Sub | ||||
|             | Tag::Mul | ||||
|             | Tag::Div | ||||
|             | Tag::Rem => { | ||||
|                 let (lhs, rhs) = data.as_two_indices(); | ||||
|                 let lhs = self.visit_any(ast, lhs)?.unwrap(); | ||||
|                 let rhs = self.visit_any(ast, rhs)?.unwrap(); | ||||
| 
 | ||||
|                 if lhs != rhs { | ||||
|                     self.errors.push(Error { | ||||
|                         idx, | ||||
|                         kind: ErrorKind::MismatchingTypes, | ||||
|                     }); | ||||
|                 } | ||||
| 
 | ||||
|                 Some(lhs) | ||||
|             } | ||||
|             Tag::Assign => self.visit_assign(ast, idx)?, | ||||
|             Tag::SubscriptExpr => self.visit_subscript_expr(ast, idx)?, | ||||
|             Tag::IfExpr => self.visit_if_expr(ast, idx)?, | ||||
|             Tag::IfElseExpr => self.visit_if_else_expr(ast, idx)?, | ||||
|             Tag::Error => todo!(), | ||||
|             Tag::Undefined => todo!(), | ||||
|         }; | ||||
| 
 | ||||
|         todo!() | ||||
|     } | ||||
| 
 | ||||
|     fn visit_explicit_cast_impl( | ||||
|         &mut self, | ||||
|         ast: &'a mut Ast, | ||||
|         idx: Index, | ||||
|         expr: Index, | ||||
|         ty: Index, | ||||
|     ) -> Result<Self::Value, Self::Error> { | ||||
|         _ = self.visit_any(ast, expr)?; | ||||
|         // TODO: make sure this cast is legal
 | ||||
|         let ty = self.visit_any(ast, ty)?; | ||||
| 
 | ||||
|         Ok(ty) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_address_of_impl( | ||||
|         &mut self, | ||||
|         ast: &'a mut Ast, | ||||
|         idx: Index, | ||||
|         expr: Index, | ||||
|     ) -> Result<Self::Value, Self::Error> { | ||||
|         self.visit_any(ast, expr) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_deref_impl( | ||||
|         &mut self, | ||||
|         ast: &'a mut Ast, | ||||
|         idx: Index, | ||||
|         expr: Index, | ||||
|     ) -> Result<Self::Value, Self::Error> { | ||||
|         let ty = self.visit_any(ast, expr)?.unwrap(); | ||||
|         if let intern::Key::PointerType { pointee, .. } = self.ip.get_key(ty) { | ||||
|             Ok(Some(pointee)) | ||||
|         } else { | ||||
|             Ok(None) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn visit_place_to_value_conversion_impl( | ||||
|         &mut self, | ||||
|         ast: &'a mut Ast, | ||||
|         idx: Index, | ||||
|         expr: Index, | ||||
|     ) -> Result<Self::Value, Self::Error> { | ||||
|         let ty = self.visit_any(ast, expr)?; | ||||
| 
 | ||||
|         if let Some(ty) = ty { | ||||
|             Ok(self.ip.try_get_pointee_type(ty)) | ||||
|         } else { | ||||
|             self.errors.push(Error { | ||||
|                 idx, | ||||
|                 kind: ErrorKind::DerefNonPointer, | ||||
|             }); | ||||
|             Ok(None) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn visit_value_to_place_conversion_impl( | ||||
|         &mut self, | ||||
|         ast: &'a mut Ast, | ||||
|         idx: Index, | ||||
|         expr: Index, | ||||
|     ) -> Result<Self::Value, Self::Error> { | ||||
|         let ty = self.visit_any(ast, expr)?; | ||||
| 
 | ||||
|         if let Some(ty) = ty { | ||||
|             Ok(Some(self.ip.get_pointer_type(ty, None))) | ||||
|         } else { | ||||
|             Ok(None) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn visit_if_else_expr_impl( | ||||
|         &mut self, | ||||
|         ast: &'a mut Ast, | ||||
|         idx: Index, | ||||
|         cond: Index, | ||||
|         a: Index, | ||||
|         b: Index, | ||||
|     ) -> Result<Self::Value, Self::Error> { | ||||
|         self.visit_any(ast, cond)?; | ||||
|         let a = self.visit_block(ast, a)?; | ||||
|         let b = self.visit_block(ast, b)?; | ||||
| 
 | ||||
|         if a != b { | ||||
|             self.errors.push(Error { | ||||
|                 idx, | ||||
|                 kind: ErrorKind::MismatchingTypes, | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|         Ok(a) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_if_expr_impl( | ||||
|         &mut self, | ||||
|         ast: &'a mut Ast, | ||||
|         idx: Index, | ||||
|         cond: Index, | ||||
|         body: Index, | ||||
|     ) -> Result<Self::Value, Self::Error> { | ||||
|         self.visit_any(ast, cond)?; | ||||
|         self.visit_block(ast, body)?; | ||||
| 
 | ||||
|         Ok(None) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_subscript_expr_impl( | ||||
|         &mut self, | ||||
|         ast: &'a mut Ast, | ||||
|         idx: Index, | ||||
|         lhs: Index, | ||||
|         index: Index, | ||||
|     ) -> Result<Self::Value, Self::Error> { | ||||
|         let lhs = self.visit_any(ast, lhs)?.unwrap(); | ||||
|         let index = self.visit_any(ast, index)?.unwrap(); | ||||
| 
 | ||||
|         if index != intern::Index::USIZE { | ||||
|             self.errors.push(Error { | ||||
|                 idx, | ||||
|                 kind: ErrorKind::MismatchingTypes, | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|         let pointee = self.ip.try_get_pointee_type(lhs).unwrap(); | ||||
|         let pointer = self.ip.get_pointer_type(pointee, None); | ||||
| 
 | ||||
|         Ok(Some(pointer)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_assign_impl( | ||||
|         &mut self, | ||||
|         ast: &'a mut Ast, | ||||
|         idx: Index, | ||||
|         lhs: Index, | ||||
|         rhs: Index, | ||||
|     ) -> Result<Self::Value, Self::Error> { | ||||
|         let lhs = self.visit_any(ast, lhs)?.unwrap(); | ||||
|         let rhs = self.visit_any(ast, rhs)?.unwrap(); | ||||
| 
 | ||||
|         if self.ip.try_get_pointee_type(lhs) != Some(rhs) { | ||||
|             self.errors.push(Error { | ||||
|                 idx, | ||||
|                 kind: ErrorKind::MismatchingTypes, | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|         Ok(None) | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue