Allow initializing foreign structs as well

This commit is contained in:
Sofia 2025-08-04 22:33:06 +03:00
parent b93b7aa52b
commit 8a178387ca
11 changed files with 41 additions and 33 deletions

View File

@ -0,0 +1,6 @@
import foreign_struct::Vec2;
fn main() -> u32 {
let a = Vec2 {x: 16, y: 32};
return a.x;
}

View File

@ -0,0 +1 @@
struct Vec2 { x: u32, y: u32 }

View File

@ -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()

View File

@ -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));

View File

@ -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) => {

View File

@ -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();

View File

@ -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)))

View File

@ -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()
}
}
_ => {} _ => {}
} }
} }

View File

@ -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),

View File

@ -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 {

View File

@ -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