mirror of
https://github.com/edg-l/edlang.git
synced 2024-11-21 23:48:24 +00:00
feat: struct support
This commit is contained in:
parent
604dcd33c0
commit
962233f269
|
@ -1,4 +1,4 @@
|
|||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
pub use edlang_span::Span;
|
||||
|
||||
|
|
|
@ -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!(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue