place-value stuff should work now
This commit is contained in:
		
							parent
							
								
									6d70231c91
								
							
						
					
					
						commit
						1be3f29e23
					
				|  | @ -1315,6 +1315,14 @@ impl InternPool { | |||
|         }; | ||||
|         self.get_or_insert(key) | ||||
|     } | ||||
| 
 | ||||
|     pub fn try_get_pointee_type(&self, pointer: Index) -> Option<Index> { | ||||
|         match self.get_key(pointer) { | ||||
|             Key::PointerType { pointee, .. } | Key::ArrayType { pointee, .. } => Some(pointee), | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn try_get_pointer_type( | ||||
|         &self, | ||||
|         pointee: Index, | ||||
|  |  | |||
							
								
								
									
										322
									
								
								src/ast2/mod.rs
									
									
									
									
									
								
							
							
						
						
									
										322
									
								
								src/ast2/mod.rs
									
									
									
									
									
								
							|  | @ -1332,17 +1332,26 @@ impl Ast { | |||
|             | Tag::Block | ||||
|             | Tag::ParameterList | ||||
|             | Tag::File => void, | ||||
|             Tag::VarDeclAssignment | Tag::MutVarDeclAssignment => { | ||||
|             // these all evaluate to pointers
 | ||||
|             Tag::VarDecl | Tag::MutVarDecl | Tag::VarDeclAssignment | Tag::MutVarDeclAssignment => { | ||||
|                 let (_, b) = data.as_extra_range(); | ||||
|                 self.get_type_of_node(ip, cache, Index::from_u32(self.extra[b - 1]).unwrap()) | ||||
|             } | ||||
|             Tag::VarDecl | Tag::MutVarDecl => { | ||||
|                 let (a, _b) = data.as_extra_range(); | ||||
|                 self.get_type_of_node(ip, cache, Index::from_u32(self.extra[a + 1]).unwrap()) | ||||
|                 let pointee = | ||||
|                     self.get_type_of_node(ip, cache, Index::from_u32(self.extra[b - 1]).unwrap()); | ||||
| 
 | ||||
|                 ip.try_get_pointer_type( | ||||
|                     pointee, | ||||
|                     Some(PointerFlags::new(tag == Tag::VarDecl, false, false)), | ||||
|                 ) | ||||
|                 .unwrap() | ||||
|             } | ||||
|             // these all evaluate to pointers
 | ||||
|             Tag::GlobalDecl => { | ||||
|                 let (_, a) = data.as_intern_and_extra_offset(); | ||||
|                 self.get_type_of_node(ip, cache, Index::from_u32(self.extra[a]).unwrap()) | ||||
|                 let pointee = | ||||
|                     self.get_type_of_node(ip, cache, Index::from_u32(self.extra[a]).unwrap()); | ||||
| 
 | ||||
|                 ip.try_get_pointer_type(pointee, Some(PointerFlags::new(true, false, true))) | ||||
|                     .unwrap() | ||||
|             } | ||||
|             Tag::FunctionDecl => self.get_type_of_node(ip, cache, data.as_two_indices().0), | ||||
|             Tag::FunctionProto => { | ||||
|  | @ -1392,10 +1401,11 @@ impl Ast { | |||
|                 let (_, a) = data.as_two_indices(); | ||||
|                 self.get_type_of_node(ip, cache, a) | ||||
|             } | ||||
|             // this evaluates to a pointer
 | ||||
|             Tag::FieldAccess => { | ||||
|                 let (ty_expr, name) = data.as_index_intern(); | ||||
|                 let ty = self.get_type_of_node(ip, cache, ty_expr); | ||||
|                 match ip.get_key(ty) { | ||||
|                 let pointee = match ip.get_key(ty) { | ||||
|                     intern::Key::PointerType { pointee, .. } | ||||
|                         if let intern::Key::StructType { fields, .. } = ip.get_key(pointee) => | ||||
|                     { | ||||
|  | @ -1415,7 +1425,35 @@ impl Ast { | |||
|                     _ => { | ||||
|                         unimplemented!() | ||||
|                     } | ||||
|                 }; | ||||
| 
 | ||||
|                 ip.try_get_pointer_type(pointee, None).unwrap() | ||||
|             } | ||||
|             // this evaluates to a pointer
 | ||||
|             Tag::SubscriptExpr => { | ||||
|                 let ty = self.get_type_of_node(ip, cache, data.as_two_indices().0); | ||||
|                 match ip.get_key(ty) { | ||||
|                     intern::Key::PointerType { .. } | intern::Key::ArrayType { .. } => { | ||||
|                         // note: because of value-to-place and place-to-value,
 | ||||
|                         // this is actually a pointer.
 | ||||
|                         // pointee
 | ||||
|                         ty | ||||
|                     } | ||||
|                     _ => { | ||||
|                         eprintln!("lhs of subscript is not an array or pointer!"); | ||||
|                         void | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             // this evaluates to a pointer
 | ||||
|             Tag::AddressOf => { | ||||
|                 let ty = self.get_type_of_node(ip, cache, data.as_index()); | ||||
|                 // TODO: find out of the expression is const, volatile for flags
 | ||||
| 
 | ||||
|                 // ip.try_get_pointer_type(ty, None).unwrap()
 | ||||
|                 // note: because of value-to-place and place-to-value,
 | ||||
|                 // this is actually the same type.
 | ||||
|                 ty | ||||
|             } | ||||
|             Tag::Deref => { | ||||
|                 let ty = self.get_type_of_node(ip, cache, data.as_index()); | ||||
|  | @ -1426,25 +1464,15 @@ impl Ast { | |||
|                     void | ||||
|                 } | ||||
|             } | ||||
|             Tag::SubscriptExpr => { | ||||
|                 let ty = self.get_type_of_node(ip, cache, data.as_two_indices().0); | ||||
|                 match ip.get_key(ty) { | ||||
|                     intern::Key::PointerType { pointee, .. } | ||||
|                     | intern::Key::ArrayType { pointee, .. } => pointee, | ||||
|                     _ => { | ||||
|                         eprintln!("lhs of subscript is not an array or pointer!"); | ||||
|                         void | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             Tag::AddressOf => { | ||||
|             Tag::ValueToPlaceConversion => { | ||||
|                 let ty = self.get_type_of_node(ip, cache, data.as_index()); | ||||
|                 // TODO: find out of the expression is const, volatile for flags
 | ||||
|                 ip.try_get_pointer_type(ty, None).unwrap() | ||||
|             } | ||||
|             Tag::ValueToPlaceConversion | Tag::PlaceToValueConversion | Tag::Not | Tag::Negate => { | ||||
|                 self.get_type_of_node(ip, cache, data.as_index()) | ||||
|             Tag::PlaceToValueConversion => { | ||||
|                 let ty = self.get_type_of_node(ip, cache, data.as_index()); | ||||
|                 ip.try_get_pointee_type(ty).unwrap() | ||||
|             } | ||||
|             Tag::Not | Tag::Negate => self.get_type_of_node(ip, cache, data.as_index()), | ||||
|             Tag::Or | ||||
|             | Tag::And | ||||
|             | Tag::BitOr | ||||
|  | @ -1667,7 +1695,10 @@ impl Ast { | |||
|                 Tag::ReturnExprStmt => are_children_comptime(self, cache), | ||||
|                 Tag::MutVarDecl | Tag::MutVarDeclAssignment => false, | ||||
|                 // Tag::VarDecl => true,
 | ||||
|                 Tag::VarDeclAssignment => are_children_comptime(self, cache), | ||||
|                 // Tag::ValueToPlaceConversion => false,
 | ||||
|                 Tag::PlaceToValueConversion | Tag::VarDeclAssignment => { | ||||
|                     are_children_comptime(self, cache) | ||||
|                 } | ||||
|                 Tag::GlobalDecl => true, | ||||
|                 Tag::StructDecl => true, | ||||
|                 Tag::FieldDecl => true, | ||||
|  | @ -1707,7 +1738,7 @@ impl Ast { | |||
|                 | Tag::Sub | ||||
|                 | Tag::Mul | ||||
|                 | Tag::Div | ||||
|                 | Tag::SubscriptExpr | ||||
|                 | Tag::SubscriptExpr // TODO: add array decl expression
 | ||||
|                 | Tag::Rem => are_children_comptime(self, cache), | ||||
|                 Tag::Assign => { | ||||
|                     let (left, _) = data.as_two_indices(); | ||||
|  | @ -1771,7 +1802,12 @@ impl Ast { | |||
|                     Index::from_u32(self.extra[a + 1]).unwrap(), | ||||
|                 ) | ||||
|             } | ||||
|             Tag::DeclRef => self.comptime_value_of_node(ip, pointer_bits, cache, data.as_index()), | ||||
|             Tag::SubscriptExpr => { | ||||
|                 todo!() | ||||
|             } | ||||
|             Tag::PlaceToValueConversion | Tag::DeclRef => { | ||||
|                 self.comptime_value_of_node(ip, pointer_bits, cache, data.as_index()) | ||||
|             } | ||||
|             Tag::ExplicitCast => { | ||||
|                 let (expr, ty) = data.as_two_indices(); | ||||
|                 let ty = ip.as_ast1_type(intern::AMD64_POINTER_BITS, self.datas[ty].as_intern()); | ||||
|  | @ -4681,6 +4717,28 @@ pub trait AstVisitorTrait { | |||
|         _ = (ast, idx); | ||||
|         Err(Self::UNIMPL) | ||||
|     } | ||||
|     fn visit_value_to_place_conversion( | ||||
|         &mut self, | ||||
|         ast: &mut Ast, | ||||
|         idx: Index, | ||||
|     ) -> Result<Self::Value, Self::Error> { | ||||
|         let idx = ast | ||||
|             .get_node_data_for_tag(idx, Tag::ValueToPlaceConversion) | ||||
|             .unwrap() | ||||
|             .as_index(); | ||||
|         self.visit_any(ast, idx) | ||||
|     } | ||||
|     fn visit_place_to_value_conversion( | ||||
|         &mut self, | ||||
|         ast: &mut Ast, | ||||
|         idx: Index, | ||||
|     ) -> Result<Self::Value, Self::Error> { | ||||
|         let idx = ast | ||||
|             .get_node_data_for_tag(idx, Tag::PlaceToValueConversion) | ||||
|             .unwrap() | ||||
|             .as_index(); | ||||
|         self.visit_any(ast, idx) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_any(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { | ||||
|         use visitor::AstExt; | ||||
|  | @ -4741,6 +4799,8 @@ pub trait AstVisitorTrait { | |||
|             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::PlaceToValueConversion => self.visit_place_to_value_conversion(ast, idx), | ||||
|             Tag::ValueToPlaceConversion => self.visit_value_to_place_conversion(ast, idx), | ||||
|             Tag::Error => todo!(), | ||||
|             Tag::Undefined => todo!(), | ||||
|             _ => todo!(), | ||||
|  | @ -4823,6 +4883,50 @@ pub mod ir { | |||
|             Ok(None) | ||||
|         } | ||||
| 
 | ||||
|         fn visit_place_to_value_conversion( | ||||
|             &mut self, | ||||
|             ast: &mut super::Ast, | ||||
|             idx: Index, | ||||
|         ) -> Result<Self::Value, Self::Error> { | ||||
|             let data = ast.expect_node_data_for_tag(idx, super::Tag::PlaceToValueConversion); | ||||
|             let expr = data.as_index(); | ||||
| 
 | ||||
|             // idx's (this) type is the pointee type
 | ||||
|             let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, idx); | ||||
| 
 | ||||
|             let expr = self.visit_any(ast, expr)?.unwrap(); | ||||
| 
 | ||||
|             let ir = self.ir.push(Inst::Load(ty), Some(triples::Data::lhs(expr))); | ||||
|             Ok(Some(ir)) | ||||
|         } | ||||
| 
 | ||||
|         fn visit_value_to_place_conversion( | ||||
|             &mut self, | ||||
|             ast: &mut super::Ast, | ||||
|             idx: Index, | ||||
|         ) -> Result<Self::Value, Self::Error> { | ||||
|             let data = ast.expect_node_data_for_tag(idx, super::Tag::ValueToPlaceConversion); | ||||
|             let expr = data.as_index(); | ||||
| 
 | ||||
|             // expr's type is the pointee type
 | ||||
|             let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, expr); | ||||
| 
 | ||||
|             let expr = self.visit_any(ast, expr)?.unwrap(); | ||||
| 
 | ||||
|             let info = self.ip.size_of_type(ty, AMD64_POINTER_TYPE_INFO); | ||||
| 
 | ||||
|             let alloca = self.ir.push( | ||||
|                 Inst::Alloca, | ||||
|                 Some(triples::Data::new(info.size(), info.align())), | ||||
|             ); | ||||
| 
 | ||||
|             _ = self | ||||
|                 .ir | ||||
|                 .push(Inst::Store(ty), Some(triples::Data::new(expr, alloca))); | ||||
| 
 | ||||
|             Ok(Some(alloca)) | ||||
|         } | ||||
| 
 | ||||
|         fn visit_decl_ref( | ||||
|             &mut self, | ||||
|             ast: &mut super::Ast, | ||||
|  | @ -4831,7 +4935,9 @@ pub mod ir { | |||
|             let data = ast.expect_node_data_for_tag(idx, super::Tag::DeclRef); | ||||
|             let decl = data.as_index(); | ||||
| 
 | ||||
|             todo!() | ||||
|             let alloca = self.ref_lookup.get(&decl).cloned().expect("declref"); | ||||
| 
 | ||||
|             Ok(Some(alloca)) | ||||
|         } | ||||
| 
 | ||||
|         fn visit_var_decl( | ||||
|  | @ -4839,118 +4945,31 @@ pub mod ir { | |||
|             ast: &mut super::Ast, | ||||
|             idx: Index, | ||||
|         ) -> Result<Self::Value, Self::Error> { | ||||
|             let data = ast.expect_node_data_for_tag(idx, super::Tag::VarDecl); | ||||
|             let (a, _) = data.as_extra_range(); | ||||
| 
 | ||||
|             let ty = Index::from_u32(ast.extra[a + 1]).unwrap(); | ||||
|             let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, ty); | ||||
|             let info = self.ip.size_of_type(ty, AMD64_POINTER_TYPE_INFO); | ||||
| 
 | ||||
|             let alloca = self.ir.push( | ||||
|                 Inst::Alloca, | ||||
|                 Some(triples::Data::new(info.size(), info.align())), | ||||
|             ); | ||||
|             self.ref_lookup.insert(idx, alloca); | ||||
| 
 | ||||
|             Ok(Some(alloca)) | ||||
|             self.visit_var_decl_common(ast, idx) | ||||
|         } | ||||
| 
 | ||||
|         fn visit_mut_var_decl( | ||||
|             &mut self, | ||||
|             ast: &mut super::Ast, | ||||
|             idx: Index, | ||||
|         ) -> Result<Self::Value, Self::Error> { | ||||
|             let data = ast.expect_node_data_for_tag(idx, super::Tag::MutVarDecl); | ||||
|             let (a, _) = data.as_extra_range(); | ||||
| 
 | ||||
|             let ty = Index::from_u32(ast.extra[a + 1]).unwrap(); | ||||
|             let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, ty); | ||||
|             let info = self.ip.size_of_type(ty, AMD64_POINTER_TYPE_INFO); | ||||
| 
 | ||||
|             let alloca = self.ir.push( | ||||
|                 Inst::Alloca, | ||||
|                 Some(triples::Data::new(info.size(), info.align())), | ||||
|             ); | ||||
|             self.ref_lookup.insert(idx, alloca); | ||||
| 
 | ||||
|             Ok(Some(alloca)) | ||||
|             self.visit_var_decl_common(ast, idx) | ||||
|         } | ||||
| 
 | ||||
|         fn visit_var_assign_decl( | ||||
|             &mut self, | ||||
|             ast: &mut super::Ast, | ||||
|             idx: Index, | ||||
|         ) -> Result<Self::Value, Self::Error> { | ||||
|             let data = ast.expect_node_data_for_tag(idx, super::Tag::VarDeclAssignment); | ||||
|             let (a, b) = data.as_extra_range(); | ||||
| 
 | ||||
|             let range = &ast.extra[a..b]; | ||||
|             let _name = range.get(0).unwrap(); | ||||
|             let expr = range | ||||
|                 .get(1) | ||||
|                 .cloned() | ||||
|                 .map(Index::from_u32) | ||||
|                 .flatten() | ||||
|                 .unwrap(); | ||||
|             let ty = range | ||||
|                 .get(2) | ||||
|                 .cloned() | ||||
|                 .map(Index::from_u32) | ||||
|                 .flatten() | ||||
|                 .unwrap_or(expr); | ||||
| 
 | ||||
|             let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, ty); | ||||
|             let info = self.ip.size_of_type(ty, AMD64_POINTER_TYPE_INFO); | ||||
| 
 | ||||
|             let alloca = self.ir.push( | ||||
|                 Inst::Alloca, | ||||
|                 Some(triples::Data::new(info.size(), info.align())), | ||||
|             ); | ||||
| 
 | ||||
|             let expr = self.visit_any(ast, expr)?.unwrap(); | ||||
|             self.ir | ||||
|                 .push(Inst::Store(ty), Some(triples::Data::new(expr, alloca))); | ||||
| 
 | ||||
|             self.ref_lookup.insert(idx, alloca); | ||||
| 
 | ||||
|             Ok(Some(alloca)) | ||||
|             self.visit_var_decl_common(ast, idx) | ||||
|         } | ||||
| 
 | ||||
|         fn visit_mut_var_assign_decl( | ||||
|             &mut self, | ||||
|             ast: &mut super::Ast, | ||||
|             idx: Index, | ||||
|         ) -> Result<Self::Value, Self::Error> { | ||||
|             let data = ast.expect_node_data_for_tag(idx, super::Tag::MutVarDeclAssignment); | ||||
|             let (a, b) = data.as_extra_range(); | ||||
| 
 | ||||
|             let range = &ast.extra[a..b]; | ||||
|             let _name = range.get(0).unwrap(); | ||||
|             let expr = range | ||||
|                 .get(1) | ||||
|                 .cloned() | ||||
|                 .map(Index::from_u32) | ||||
|                 .flatten() | ||||
|                 .unwrap(); | ||||
|             let ty = range | ||||
|                 .get(2) | ||||
|                 .cloned() | ||||
|                 .map(Index::from_u32) | ||||
|                 .flatten() | ||||
|                 .unwrap_or(expr); | ||||
| 
 | ||||
|             let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, ty); | ||||
|             let info = self.ip.size_of_type(ty, AMD64_POINTER_TYPE_INFO); | ||||
| 
 | ||||
|             let alloca = self.ir.push( | ||||
|                 Inst::Alloca, | ||||
|                 Some(triples::Data::new(info.size(), info.align())), | ||||
|             ); | ||||
| 
 | ||||
|             let expr = self.visit_any(ast, expr)?.unwrap(); | ||||
|             self.ir | ||||
|                 .push(Inst::Store(ty), Some(triples::Data::new(expr, alloca))); | ||||
| 
 | ||||
|             self.ref_lookup.insert(idx, alloca); | ||||
| 
 | ||||
|             Ok(Some(alloca)) | ||||
|             self.visit_var_decl_common(ast, idx) | ||||
|         } | ||||
| 
 | ||||
|         fn visit_return( | ||||
|  | @ -5001,6 +5020,8 @@ pub mod ir { | |||
|         ) -> Result<Self::Value, Self::Error> { | ||||
|             let data = ast.expect_node_data_for_tag(idx, super::Tag::SubscriptExpr); | ||||
|             let (lhs, index) = data.as_two_indices(); | ||||
| 
 | ||||
|             // pointer type
 | ||||
|             let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, idx); | ||||
| 
 | ||||
|             let lhs = self.visit_any(ast, lhs)?.unwrap(); | ||||
|  | @ -5525,6 +5546,65 @@ pub mod ir { | |||
|     } | ||||
| 
 | ||||
|     impl IrFunctionBuilder<'_> { | ||||
|         fn visit_var_decl_common( | ||||
|             &mut self, | ||||
|             ast: &mut super::Ast, | ||||
|             idx: Index, | ||||
|         ) -> Result<Option<u32>, Error> { | ||||
|             let (tag, data) = ast.get_node_tag_and_data(idx); | ||||
|             let (a, b) = data.as_extra_range(); | ||||
| 
 | ||||
|             let range = &ast.extra[a..b]; | ||||
|             let _name = range.get(0).unwrap(); | ||||
| 
 | ||||
|             let (expr, typed_index) = match tag { | ||||
|                 super::Tag::VarDecl | super::Tag::MutVarDecl => { | ||||
|                     let typed_index = range | ||||
|                         .get(1) | ||||
|                         .cloned() | ||||
|                         .map(Index::from_u32) | ||||
|                         .flatten() | ||||
|                         .unwrap(); | ||||
|                     (None, typed_index) | ||||
|                 } | ||||
|                 super::Tag::VarDeclAssignment | super::Tag::MutVarDeclAssignment => { | ||||
|                     let expr = range | ||||
|                         .get(1) | ||||
|                         .cloned() | ||||
|                         .map(Index::from_u32) | ||||
|                         .flatten() | ||||
|                         .unwrap(); | ||||
|                     let typed_index = range | ||||
|                         .get(2) | ||||
|                         .cloned() | ||||
|                         .map(Index::from_u32) | ||||
|                         .flatten() | ||||
|                         .unwrap_or(expr); | ||||
|                     (Some(expr), typed_index) | ||||
|                 } | ||||
|                 _ => unreachable!(), | ||||
|             }; | ||||
| 
 | ||||
|             let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, typed_index); | ||||
|             let info = self.ip.size_of_type(ty, AMD64_POINTER_TYPE_INFO); | ||||
| 
 | ||||
|             let alloca = self.ir.push( | ||||
|                 Inst::Alloca, | ||||
|                 Some(triples::Data::new(info.size(), info.align())), | ||||
|             ); | ||||
| 
 | ||||
|             if let Some(idx) = expr { | ||||
|                 let expr = self.visit_any(ast, idx)?.unwrap(); | ||||
|                 _ = self | ||||
|                     .ir | ||||
|                     .push(Inst::Store(ty), Some(triples::Data::new(expr, alloca))); | ||||
|             } | ||||
| 
 | ||||
|             self.ref_lookup.insert(idx, alloca); | ||||
| 
 | ||||
|             Ok(Some(alloca)) | ||||
|         } | ||||
| 
 | ||||
|         /// handles all binary operations that don't short circuit and visit
 | ||||
|         /// both lhs and rhs.
 | ||||
|         fn visit_binop_expr( | ||||
|  |  | |||
|  | @ -159,10 +159,13 @@ pub enum Inst { | |||
|     Constant, | ||||
|     /// size, align
 | ||||
|     Alloca, | ||||
|     /// (pointee type)
 | ||||
|     /// src
 | ||||
|     Load(intern::Index), | ||||
|     /// (pointee type)
 | ||||
|     /// src, dst
 | ||||
|     Store(intern::Index), | ||||
|     /// (pointer type)
 | ||||
|     /// ptr, index,
 | ||||
|     GetElementPtr(intern::Index), | ||||
|     /// size, align
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue