Allow initializing foreign structs as well
This commit is contained in:
		
							parent
							
								
									b93b7aa52b
								
							
						
					
					
						commit
						8a178387ca
					
				
							
								
								
									
										6
									
								
								examples/foreign_init.reid
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								examples/foreign_init.reid
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | |||||||
|  | import foreign_struct::Vec2; | ||||||
|  | 
 | ||||||
|  | fn main() -> u32 { | ||||||
|  |     let a = Vec2 {x: 16, y: 32}; | ||||||
|  |     return a.x; | ||||||
|  | } | ||||||
							
								
								
									
										1
									
								
								examples/foreign_struct.reid
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								examples/foreign_struct.reid
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | struct Vec2 { x: u32, y: u32 } | ||||||
| @ -381,7 +381,7 @@ impl ast::Expression { | |||||||
|                 Box::new(idx_expr.process(module_id)), |                 Box::new(idx_expr.process(module_id)), | ||||||
|             ), |             ), | ||||||
|             ast::ExpressionKind::StructExpression(struct_init) => mir::ExprKind::Struct( |             ast::ExpressionKind::StructExpression(struct_init) => mir::ExprKind::Struct( | ||||||
|                 struct_init.name.clone(), |                 CustomTypeKey(struct_init.name.clone(), module_id), | ||||||
|                 struct_init |                 struct_init | ||||||
|                     .fields |                     .fields | ||||||
|                     .iter() |                     .iter() | ||||||
|  | |||||||
| @ -151,11 +151,11 @@ impl mir::Expression { | |||||||
|                     allocated.extend(expression.allocate(scope)); |                     allocated.extend(expression.allocate(scope)); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             mir::ExprKind::Struct(name, items) => { |             mir::ExprKind::Struct(key, items) => { | ||||||
|                 let (_, ty) = self.return_type(&Default::default(), scope.mod_id).unwrap(); |                 let (_, ty) = self.return_type(&Default::default(), scope.mod_id).unwrap(); | ||||||
|                 let allocation = scope |                 let allocation = scope | ||||||
|                     .block |                     .block | ||||||
|                     .build_named(name, Instr::Alloca(ty.get_type(scope.type_values))) |                     .build_named(key.0.clone(), Instr::Alloca(ty.get_type(scope.type_values))) | ||||||
|                     .unwrap(); |                     .unwrap(); | ||||||
|                 allocated.push(Allocation(self.1, ty, allocation)); |                 allocated.push(Allocation(self.1, ty, allocation)); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1208,10 +1208,9 @@ impl mir::Expression { | |||||||
|                     )) |                     )) | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             mir::ExprKind::Struct(name, items) => { |             mir::ExprKind::Struct(key, items) => { | ||||||
|                 let type_key = CustomTypeKey(name.clone(), scope.module_id); |  | ||||||
|                 let ty = Type::CustomType({ |                 let ty = Type::CustomType({ | ||||||
|                     let Some(a) = scope.type_values.get(&type_key) else { |                     let Some(a) = scope.type_values.get(&key) else { | ||||||
|                         return Ok(None); |                         return Ok(None); | ||||||
|                     }; |                     }; | ||||||
|                     *a |                     *a | ||||||
| @ -1220,20 +1219,20 @@ impl mir::Expression { | |||||||
|                 let TypeDefinition { |                 let TypeDefinition { | ||||||
|                     kind: TypeDefinitionKind::Struct(struct_ty), |                     kind: TypeDefinitionKind::Struct(struct_ty), | ||||||
|                     .. |                     .. | ||||||
|                 } = scope.types.get(scope.type_values.get(&type_key).unwrap()).unwrap(); |                 } = scope.types.get(scope.type_values.get(&key).unwrap()).unwrap(); | ||||||
| 
 | 
 | ||||||
|                 let indices = struct_ty.0.iter().enumerate(); |                 let indices = struct_ty.0.iter().enumerate(); | ||||||
| 
 | 
 | ||||||
|                 let load_n = format!("{}.load", name); |                 let load_n = format!("{:?}.load", key); | ||||||
| 
 | 
 | ||||||
|                 let struct_ptr = scope |                 let struct_ptr = scope | ||||||
|                     .allocate(&self.1, &TypeKind::CustomType(type_key.clone())) |                     .allocate(&self.1, &TypeKind::CustomType(key.clone())) | ||||||
|                     .unwrap() |                     .unwrap() | ||||||
|                     .maybe_location(&mut scope.block, location.clone()); |                     .maybe_location(&mut scope.block, location.clone()); | ||||||
| 
 | 
 | ||||||
|                 for (field_n, exp, _) in items { |                 for (field_n, exp, _) in items { | ||||||
|                     let gep_n = format!("{}.{}.gep", name, field_n); |                     let gep_n = format!("{:?}.{}.gep", key, field_n); | ||||||
|                     let store_n = format!("{}.{}.store", name, field_n); |                     let store_n = format!("{:?}.{}.store", key, field_n); | ||||||
|                     let i = indices.clone().find(|(_, f)| f.0 == *field_n).unwrap().0; |                     let i = indices.clone().find(|(_, f)| f.0 == *field_n).unwrap().0; | ||||||
| 
 | 
 | ||||||
|                     let elem_ptr = scope |                     let elem_ptr = scope | ||||||
| @ -1254,7 +1253,7 @@ impl mir::Expression { | |||||||
| 
 | 
 | ||||||
|                 Some(StackValue( |                 Some(StackValue( | ||||||
|                     StackValueKind::Literal(struct_val), |                     StackValueKind::Literal(struct_val), | ||||||
|                     TypeKind::CustomType(type_key), |                     TypeKind::CustomType(key.clone()), | ||||||
|                 )) |                 )) | ||||||
|             } |             } | ||||||
|             mir::ExprKind::Borrow(expr, mutable) => { |             mir::ExprKind::Borrow(expr, mutable) => { | ||||||
|  | |||||||
| @ -276,8 +276,8 @@ impl Display for ExprKind { | |||||||
|                 } |                 } | ||||||
|                 f.write_char(']') |                 f.write_char(']') | ||||||
|             } |             } | ||||||
|             ExprKind::Struct(name, items) => { |             ExprKind::Struct(key, items) => { | ||||||
|                 write!(f, "{} ", name)?; |                 write!(f, "{:?} ", key)?; | ||||||
| 
 | 
 | ||||||
|                 f.write_char('{')?; |                 f.write_char('{')?; | ||||||
|                 let mut state = Default::default(); |                 let mut state = Default::default(); | ||||||
|  | |||||||
| @ -416,10 +416,7 @@ impl Expression { | |||||||
|                 )) |                 )) | ||||||
|             } |             } | ||||||
|             Accessed(_, type_kind, ..) => Ok((ReturnKind::Soft, type_kind.clone())), |             Accessed(_, type_kind, ..) => Ok((ReturnKind::Soft, type_kind.clone())), | ||||||
|             Struct(name, _) => Ok(( |             Struct(key, _) => Ok((ReturnKind::Soft, TypeKind::CustomType(key.clone()))), | ||||||
|                 ReturnKind::Soft, |  | ||||||
|                 TypeKind::CustomType(CustomTypeKey(name.clone(), mod_id)), |  | ||||||
|             )), |  | ||||||
|             Borrow(expr, mutable) => { |             Borrow(expr, mutable) => { | ||||||
|                 let ret_type = expr.return_type(refs, mod_id)?; |                 let ret_type = expr.return_type(refs, mod_id)?; | ||||||
|                 Ok((ret_type.0, TypeKind::Borrow(Box::new(ret_type.1), *mutable))) |                 Ok((ret_type.0, TypeKind::Borrow(Box::new(ret_type.1), *mutable))) | ||||||
|  | |||||||
| @ -441,7 +441,7 @@ impl<'map> Pass for LinkerPass<'map> { | |||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn module(&mut self, module: &mut Module, mut state: PassState<Self::Data, Self::TError>) -> PassResult { |     fn module(&mut self, module: &mut Module, state: PassState<Self::Data, Self::TError>) -> PassResult { | ||||||
|         let extern_types = &state.scope.data.extern_imported_types.get(&module.module_id); |         let extern_types = &state.scope.data.extern_imported_types.get(&module.module_id); | ||||||
|         if let Some(extern_types) = extern_types { |         if let Some(extern_types) = extern_types { | ||||||
|             for ty in &mut module.typedefs { |             for ty in &mut module.typedefs { | ||||||
| @ -511,6 +511,13 @@ impl<'map> Pass for LinkerPass<'map> { | |||||||
|                 super::ExprKind::AssociatedFunctionCall(type_kind, _) => { |                 super::ExprKind::AssociatedFunctionCall(type_kind, _) => { | ||||||
|                     *type_kind = type_kind.update_imported(extern_types, mod_id) |                     *type_kind = type_kind.update_imported(extern_types, mod_id) | ||||||
|                 } |                 } | ||||||
|  |                 super::ExprKind::Struct(key, _) => { | ||||||
|  |                     *key = if let Some(mod_id) = extern_types.get(&key.0) { | ||||||
|  |                         CustomTypeKey(key.0.clone(), *mod_id) | ||||||
|  |                     } else { | ||||||
|  |                         key.clone() | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|                 _ => {} |                 _ => {} | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -264,7 +264,7 @@ pub enum ExprKind { | |||||||
|     Indexed(Box<Expression>, TypeKind, Box<Expression>), |     Indexed(Box<Expression>, TypeKind, Box<Expression>), | ||||||
|     Accessed(Box<Expression>, TypeKind, String, Metadata), |     Accessed(Box<Expression>, TypeKind, String, Metadata), | ||||||
|     Array(Vec<Expression>), |     Array(Vec<Expression>), | ||||||
|     Struct(String, Vec<(String, Expression, Metadata)>), |     Struct(CustomTypeKey, Vec<(String, Expression, Metadata)>), | ||||||
|     Literal(Literal), |     Literal(Literal), | ||||||
|     BinOp(BinaryOperator, Box<Expression>, Box<Expression>, TypeKind), |     BinOp(BinaryOperator, Box<Expression>, Box<Expression>, TypeKind), | ||||||
|     FunctionCall(FunctionCall), |     FunctionCall(FunctionCall), | ||||||
|  | |||||||
| @ -627,15 +627,14 @@ impl Expression { | |||||||
|                     Err(ErrorKind::TriedAccessingNonStruct(expr_ty)) |                     Err(ErrorKind::TriedAccessingNonStruct(expr_ty)) | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             ExprKind::Struct(struct_name, items) => { |             ExprKind::Struct(struct_key, items) => { | ||||||
|                 let type_key = CustomTypeKey(struct_name.clone(), state.module_id.unwrap()); |  | ||||||
|                 let struct_def = state |                 let struct_def = state | ||||||
|                     .scope |                     .scope | ||||||
|                     .get_struct_type(&type_key) |                     .get_struct_type(&struct_key) | ||||||
|                     .ok_or(ErrorKind::NoSuchType(struct_name.clone(), type_key.1))? |                     .ok_or(ErrorKind::NoSuchType(struct_key.0.clone(), struct_key.1))? | ||||||
|                     .clone(); |                     .clone(); | ||||||
| 
 | 
 | ||||||
|                 let mut expected_fields = if let Some(struct_ty) = state.scope.get_struct_type(&type_key) { |                 let mut expected_fields = if let Some(struct_ty) = state.scope.get_struct_type(&struct_key) { | ||||||
|                     struct_ty.0.iter().map(|f| f.0.clone()).collect() |                     struct_ty.0.iter().map(|f| f.0.clone()).collect() | ||||||
|                 } else { |                 } else { | ||||||
|                     HashSet::new() |                     HashSet::new() | ||||||
| @ -646,7 +645,7 @@ impl Expression { | |||||||
|                     let expected_ty = state.or_else( |                     let expected_ty = state.or_else( | ||||||
|                         struct_def |                         struct_def | ||||||
|                             .get_field_ty(field_name) |                             .get_field_ty(field_name) | ||||||
|                             .ok_or(ErrorKind::NoSuchField(format!("{}.{}", struct_name, field_name))), |                             .ok_or(ErrorKind::NoSuchField(format!("{:?}.{}", struct_key, field_name))), | ||||||
|                         &TypeKind::Vague(VagueType::Unknown), |                         &TypeKind::Vague(VagueType::Unknown), | ||||||
|                         field_expr.1, |                         field_expr.1, | ||||||
|                     ); |                     ); | ||||||
| @ -668,7 +667,7 @@ impl Expression { | |||||||
|                     self.1, |                     self.1, | ||||||
|                 ); |                 ); | ||||||
| 
 | 
 | ||||||
|                 Ok(TypeKind::CustomType(type_key)) |                 Ok(TypeKind::CustomType(struct_key.clone())) | ||||||
|             } |             } | ||||||
|             ExprKind::Borrow(expr, mutable) => { |             ExprKind::Borrow(expr, mutable) => { | ||||||
|                 let hint_t = if let HintKind::Coerce(hint_t) = hint_t { |                 let hint_t = if let HintKind::Coerce(hint_t) = hint_t { | ||||||
|  | |||||||
| @ -553,12 +553,11 @@ impl Expression { | |||||||
|                     _ => Ok(type_refs.from_type(&TypeKind::Vague(VagueType::Unknown)).unwrap()), |                     _ => Ok(type_refs.from_type(&TypeKind::Vague(VagueType::Unknown)).unwrap()), | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             ExprKind::Struct(struct_name, fields) => { |             ExprKind::Struct(struct_key, fields) => { | ||||||
|                 let type_key = CustomTypeKey(struct_name.clone(), state.module_id.unwrap()); |  | ||||||
|                 let expected_struct_ty = state |                 let expected_struct_ty = state | ||||||
|                     .scope |                     .scope | ||||||
|                     .get_struct_type(&type_key) |                     .get_struct_type(&struct_key) | ||||||
|                     .ok_or(ErrorKind::NoSuchType(struct_name.clone(), state.module_id.unwrap()))? |                     .ok_or(ErrorKind::NoSuchType(struct_key.0.clone(), state.module_id.unwrap()))? | ||||||
|                     .clone(); |                     .clone(); | ||||||
|                 for field in fields { |                 for field in fields { | ||||||
|                     if let Some(expected_field_ty) = expected_struct_ty.get_field_ty(&field.0) { |                     if let Some(expected_field_ty) = expected_struct_ty.get_field_ty(&field.0) { | ||||||
| @ -568,12 +567,12 @@ impl Expression { | |||||||
|                         } |                         } | ||||||
|                     } else { |                     } else { | ||||||
|                         state.ok::<_, Infallible>( |                         state.ok::<_, Infallible>( | ||||||
|                             Err(ErrorKind::NoSuchField(format!("{}.{}", struct_name, field.0))), |                             Err(ErrorKind::NoSuchField(format!("{:?}.{}", struct_key, field.0))), | ||||||
|                             field.1 .1, |                             field.1 .1, | ||||||
|                         ); |                         ); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 Ok(type_refs.from_type(&TypeKind::CustomType(type_key.clone())).unwrap()) |                 Ok(type_refs.from_type(&TypeKind::CustomType(struct_key.clone())).unwrap()) | ||||||
|             } |             } | ||||||
|             ExprKind::Borrow(expr, mutable) => { |             ExprKind::Borrow(expr, mutable) => { | ||||||
|                 // Find variable type
 |                 // Find variable type
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user