feat: struct support

This commit is contained in:
Edgar 2024-02-18 09:44:49 +01:00
parent 604dcd33c0
commit 962233f269
No known key found for this signature in database
GPG key ID: 70ADAE8F35904387
3 changed files with 69 additions and 4 deletions

View file

@ -1,4 +1,4 @@
use std::collections::{BTreeMap, HashMap};
use std::collections::BTreeMap;
pub use edlang_span::Span;

View file

@ -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!(),
}
}

View file

@ -491,7 +491,15 @@ fn find_expr_type(builder: &mut BodyBuilder, info: &ast::Expression) -> Option<T
}
ast::Expression::Deref(_) => 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)
}
}
}