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