From 8a178387ca13a4d05ff5a7b5be4b9cdae1b05a39 Mon Sep 17 00:00:00 2001 From: sofia Date: Mon, 4 Aug 2025 22:33:06 +0300 Subject: [PATCH] Allow initializing foreign structs as well --- examples/foreign_init.reid | 6 ++++++ examples/foreign_struct.reid | 1 + reid/src/ast/process.rs | 2 +- reid/src/codegen/allocator.rs | 4 ++-- reid/src/codegen/mod.rs | 17 ++++++++--------- reid/src/mir/fmt.rs | 4 ++-- reid/src/mir/implement.rs | 5 +---- reid/src/mir/linker.rs | 9 ++++++++- reid/src/mir/mod.rs | 2 +- reid/src/mir/typecheck/typecheck.rs | 13 ++++++------- reid/src/mir/typecheck/typeinference.rs | 11 +++++------ 11 files changed, 41 insertions(+), 33 deletions(-) create mode 100644 examples/foreign_init.reid create mode 100644 examples/foreign_struct.reid diff --git a/examples/foreign_init.reid b/examples/foreign_init.reid new file mode 100644 index 0000000..970cacb --- /dev/null +++ b/examples/foreign_init.reid @@ -0,0 +1,6 @@ +import foreign_struct::Vec2; + +fn main() -> u32 { + let a = Vec2 {x: 16, y: 32}; + return a.x; +} \ No newline at end of file diff --git a/examples/foreign_struct.reid b/examples/foreign_struct.reid new file mode 100644 index 0000000..015b8dd --- /dev/null +++ b/examples/foreign_struct.reid @@ -0,0 +1 @@ +struct Vec2 { x: u32, y: u32 } diff --git a/reid/src/ast/process.rs b/reid/src/ast/process.rs index 74e6803..0bb1f70 100644 --- a/reid/src/ast/process.rs +++ b/reid/src/ast/process.rs @@ -381,7 +381,7 @@ impl ast::Expression { Box::new(idx_expr.process(module_id)), ), ast::ExpressionKind::StructExpression(struct_init) => mir::ExprKind::Struct( - struct_init.name.clone(), + CustomTypeKey(struct_init.name.clone(), module_id), struct_init .fields .iter() diff --git a/reid/src/codegen/allocator.rs b/reid/src/codegen/allocator.rs index 2598e49..174b29e 100644 --- a/reid/src/codegen/allocator.rs +++ b/reid/src/codegen/allocator.rs @@ -151,11 +151,11 @@ impl mir::Expression { 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 allocation = scope .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(); allocated.push(Allocation(self.1, ty, allocation)); diff --git a/reid/src/codegen/mod.rs b/reid/src/codegen/mod.rs index 3db128b..1d7d69e 100644 --- a/reid/src/codegen/mod.rs +++ b/reid/src/codegen/mod.rs @@ -1208,10 +1208,9 @@ impl mir::Expression { )) } } - mir::ExprKind::Struct(name, items) => { - let type_key = CustomTypeKey(name.clone(), scope.module_id); + mir::ExprKind::Struct(key, items) => { 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); }; *a @@ -1220,20 +1219,20 @@ impl mir::Expression { let TypeDefinition { 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 load_n = format!("{}.load", name); + let load_n = format!("{:?}.load", key); let struct_ptr = scope - .allocate(&self.1, &TypeKind::CustomType(type_key.clone())) + .allocate(&self.1, &TypeKind::CustomType(key.clone())) .unwrap() .maybe_location(&mut scope.block, location.clone()); for (field_n, exp, _) in items { - let gep_n = format!("{}.{}.gep", name, field_n); - let store_n = format!("{}.{}.store", name, field_n); + let gep_n = format!("{:?}.{}.gep", key, field_n); + let store_n = format!("{:?}.{}.store", key, field_n); let i = indices.clone().find(|(_, f)| f.0 == *field_n).unwrap().0; let elem_ptr = scope @@ -1254,7 +1253,7 @@ impl mir::Expression { Some(StackValue( StackValueKind::Literal(struct_val), - TypeKind::CustomType(type_key), + TypeKind::CustomType(key.clone()), )) } mir::ExprKind::Borrow(expr, mutable) => { diff --git a/reid/src/mir/fmt.rs b/reid/src/mir/fmt.rs index a2f0dc6..4cdef21 100644 --- a/reid/src/mir/fmt.rs +++ b/reid/src/mir/fmt.rs @@ -276,8 +276,8 @@ impl Display for ExprKind { } f.write_char(']') } - ExprKind::Struct(name, items) => { - write!(f, "{} ", name)?; + ExprKind::Struct(key, items) => { + write!(f, "{:?} ", key)?; f.write_char('{')?; let mut state = Default::default(); diff --git a/reid/src/mir/implement.rs b/reid/src/mir/implement.rs index b3486b2..669930f 100644 --- a/reid/src/mir/implement.rs +++ b/reid/src/mir/implement.rs @@ -416,10 +416,7 @@ impl Expression { )) } Accessed(_, type_kind, ..) => Ok((ReturnKind::Soft, type_kind.clone())), - Struct(name, _) => Ok(( - ReturnKind::Soft, - TypeKind::CustomType(CustomTypeKey(name.clone(), mod_id)), - )), + Struct(key, _) => Ok((ReturnKind::Soft, TypeKind::CustomType(key.clone()))), Borrow(expr, mutable) => { let ret_type = expr.return_type(refs, mod_id)?; Ok((ret_type.0, TypeKind::Borrow(Box::new(ret_type.1), *mutable))) diff --git a/reid/src/mir/linker.rs b/reid/src/mir/linker.rs index aefaaeb..dc95e92 100644 --- a/reid/src/mir/linker.rs +++ b/reid/src/mir/linker.rs @@ -441,7 +441,7 @@ impl<'map> Pass for LinkerPass<'map> { Ok(()) } - fn module(&mut self, module: &mut Module, mut state: PassState) -> PassResult { + fn module(&mut self, module: &mut Module, state: PassState) -> PassResult { let extern_types = &state.scope.data.extern_imported_types.get(&module.module_id); if let Some(extern_types) = extern_types { for ty in &mut module.typedefs { @@ -511,6 +511,13 @@ impl<'map> Pass for LinkerPass<'map> { super::ExprKind::AssociatedFunctionCall(type_kind, _) => { *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() + } + } _ => {} } } diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index 49309c3..13bfb97 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -264,7 +264,7 @@ pub enum ExprKind { Indexed(Box, TypeKind, Box), Accessed(Box, TypeKind, String, Metadata), Array(Vec), - Struct(String, Vec<(String, Expression, Metadata)>), + Struct(CustomTypeKey, Vec<(String, Expression, Metadata)>), Literal(Literal), BinOp(BinaryOperator, Box, Box, TypeKind), FunctionCall(FunctionCall), diff --git a/reid/src/mir/typecheck/typecheck.rs b/reid/src/mir/typecheck/typecheck.rs index fb6db94..f820808 100644 --- a/reid/src/mir/typecheck/typecheck.rs +++ b/reid/src/mir/typecheck/typecheck.rs @@ -627,15 +627,14 @@ impl Expression { Err(ErrorKind::TriedAccessingNonStruct(expr_ty)) } } - ExprKind::Struct(struct_name, items) => { - let type_key = CustomTypeKey(struct_name.clone(), state.module_id.unwrap()); + ExprKind::Struct(struct_key, items) => { let struct_def = state .scope - .get_struct_type(&type_key) - .ok_or(ErrorKind::NoSuchType(struct_name.clone(), type_key.1))? + .get_struct_type(&struct_key) + .ok_or(ErrorKind::NoSuchType(struct_key.0.clone(), struct_key.1))? .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() } else { HashSet::new() @@ -646,7 +645,7 @@ impl Expression { let expected_ty = state.or_else( struct_def .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), field_expr.1, ); @@ -668,7 +667,7 @@ impl Expression { self.1, ); - Ok(TypeKind::CustomType(type_key)) + Ok(TypeKind::CustomType(struct_key.clone())) } ExprKind::Borrow(expr, mutable) => { let hint_t = if let HintKind::Coerce(hint_t) = hint_t { diff --git a/reid/src/mir/typecheck/typeinference.rs b/reid/src/mir/typecheck/typeinference.rs index 91552f7..23567f4 100644 --- a/reid/src/mir/typecheck/typeinference.rs +++ b/reid/src/mir/typecheck/typeinference.rs @@ -553,12 +553,11 @@ impl Expression { _ => Ok(type_refs.from_type(&TypeKind::Vague(VagueType::Unknown)).unwrap()), } } - ExprKind::Struct(struct_name, fields) => { - let type_key = CustomTypeKey(struct_name.clone(), state.module_id.unwrap()); + ExprKind::Struct(struct_key, fields) => { let expected_struct_ty = state .scope - .get_struct_type(&type_key) - .ok_or(ErrorKind::NoSuchType(struct_name.clone(), state.module_id.unwrap()))? + .get_struct_type(&struct_key) + .ok_or(ErrorKind::NoSuchType(struct_key.0.clone(), state.module_id.unwrap()))? .clone(); for field in fields { if let Some(expected_field_ty) = expected_struct_ty.get_field_ty(&field.0) { @@ -568,12 +567,12 @@ impl Expression { } } else { state.ok::<_, Infallible>( - Err(ErrorKind::NoSuchField(format!("{}.{}", struct_name, field.0))), + Err(ErrorKind::NoSuchField(format!("{:?}.{}", struct_key, field.0))), 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) => { // Find variable type