diff --git a/lib/edlang_ast/src/lib.rs b/lib/edlang_ast/src/lib.rs index c2f77e27f..7e41aadad 100644 --- a/lib/edlang_ast/src/lib.rs +++ b/lib/edlang_ast/src/lib.rs @@ -1,4 +1,4 @@ -use std::collections::{BTreeMap, HashMap}; +use std::collections::BTreeMap; pub use edlang_span::Span; diff --git a/lib/edlang_codegen_llvm/src/codegen.rs b/lib/edlang_codegen_llvm/src/codegen.rs index 8ba6dc4f0..3a9e1e232 100644 --- a/lib/edlang_codegen_llvm/src/codegen.rs +++ b/lib/edlang_codegen_llvm/src/codegen.rs @@ -403,7 +403,21 @@ fn compile_fn(ctx: &ModuleCompileCtx, fn_id: DefId) -> Result<(), BuilderError> _ => unreachable!(), } } - ir::PlaceElem::Field { .. } => todo!(), + ir::PlaceElem::Field { field_idx } => { + ptr = ctx.builder.build_struct_gep( + compile_basic_type(ctx, &local_ty), + ptr, + (*field_idx) as u32, + "", + )?; + local_ty = match local_ty.kind { + ir::TypeKind::Struct(id) => { + let strc = ctx.ctx.program.structs.get(&id).unwrap(); + strc.variants[*field_idx].ty.clone() + } + _ => unreachable!(), + } + } ir::PlaceElem::Index { .. } => todo!(), } } diff --git a/lib/edlang_lowering/src/lib.rs b/lib/edlang_lowering/src/lib.rs index c3efa6768..9ead97d09 100644 --- a/lib/edlang_lowering/src/lib.rs +++ b/lib/edlang_lowering/src/lib.rs @@ -491,7 +491,15 @@ fn find_expr_type(builder: &mut BodyBuilder, info: &ast::Expression) -> Option todo!(), ast::Expression::AsRef(_, _) => todo!(), - ast::Expression::StructInit(_) => todo!(), + ast::Expression::StructInit(info) => { + let id = *builder + .get_module_body() + .symbols + .structs + .get(&info.name.name) + .expect("struct not found"); + ir::TypeKind::Struct(id) + } }) } @@ -557,7 +565,50 @@ fn lower_expr( (value, ty) } - ast::Expression::StructInit(_) => todo!(), + ast::Expression::StructInit(info) => { + let id = *builder + .get_module_body() + .symbols + .structs + .get(&info.name.name) + .expect("struct not found"); + let struct_body = builder.ctx.body.structs.get(&id).unwrap().clone(); + let ty = TypeKind::Struct(id); + let struct_local = builder.add_local(Local::temp(ty.clone())); + + let place = Place { + local: struct_local, + projection: Default::default(), + }; + + builder.statements.push(Statement { + span: None, + kind: StatementKind::StorageLive(struct_local), + }); + + for (field, value) in info.fields.iter() { + let idx = *struct_body + .name_to_idx + .get(&field.name) + .expect("failed to find field"); + let mut field_place = place.clone(); + field_place + .projection + .push(PlaceElem::Field { field_idx: idx }); + let span = value.span; + + let variant = &struct_body.variants[idx].ty.kind; + + let (value, _value_ty) = lower_expr(builder, &value.value, Some(variant)); + + builder.statements.push(Statement { + span: Some(span), + kind: StatementKind::Assign(field_place, value), + }); + } + + (RValue::Use(Operand::Move(place)), ty) + } } }