mirror of
https://github.com/edg-l/edlang.git
synced 2024-11-22 07:58:24 +00:00
struct field
This commit is contained in:
parent
a9cd4eff86
commit
79c1243f0d
|
@ -971,46 +971,9 @@ fn compile_load_operand<'ctx>(
|
||||||
locals: &HashMap<usize, PointerValue<'ctx>>,
|
locals: &HashMap<usize, PointerValue<'ctx>>,
|
||||||
op: &ir::Operand,
|
op: &ir::Operand,
|
||||||
) -> Result<(BasicValueEnum<'ctx>, TypeInfo), BuilderError> {
|
) -> Result<(BasicValueEnum<'ctx>, TypeInfo), BuilderError> {
|
||||||
// todo: implement projection
|
|
||||||
let body = ctx.ctx.program.functions.get(&fn_id).unwrap();
|
|
||||||
Ok(match op {
|
Ok(match op {
|
||||||
ir::Operand::Copy(place) => {
|
ir::Operand::Copy(place) => compile_load_place(ctx, fn_id, locals, place, true)?,
|
||||||
let pointee_ty = compile_basic_type(ctx, &body.locals[place.local].ty);
|
ir::Operand::Move(place) => compile_load_place(ctx, fn_id, locals, place, false)?,
|
||||||
let ptr = *locals.get(&place.local).unwrap();
|
|
||||||
(
|
|
||||||
ctx.builder.build_load(pointee_ty, ptr, "")?,
|
|
||||||
body.locals[place.local].ty.clone(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
ir::Operand::Move(place) => {
|
|
||||||
let mut ptr = *locals.get(&place.local).unwrap();
|
|
||||||
let mut local_ty = body.locals[place.local].ty.clone();
|
|
||||||
|
|
||||||
for proj in &place.projection {
|
|
||||||
match proj {
|
|
||||||
ir::PlaceElem::Deref => {
|
|
||||||
ptr = ctx
|
|
||||||
.builder
|
|
||||||
.build_load(compile_basic_type(ctx, &local_ty), ptr, "deref")?
|
|
||||||
.into_pointer_value();
|
|
||||||
local_ty = match local_ty.kind {
|
|
||||||
ir::TypeKind::Ptr(inner) => *inner,
|
|
||||||
ir::TypeKind::Ref(_, inner) => *inner,
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ir::PlaceElem::Field { .. } => todo!(),
|
|
||||||
ir::PlaceElem::Index { .. } => todo!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let pointee_ty = compile_basic_type(ctx, &local_ty);
|
|
||||||
|
|
||||||
(
|
|
||||||
ctx.builder.build_load(pointee_ty, ptr, "")?,
|
|
||||||
body.locals[place.local].ty.clone(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
ir::Operand::Constant(data) => match &data.kind {
|
ir::Operand::Constant(data) => match &data.kind {
|
||||||
ir::ConstKind::Value(value) => (
|
ir::ConstKind::Value(value) => (
|
||||||
compile_value(ctx, value, &data.type_info)?,
|
compile_value(ctx, value, &data.type_info)?,
|
||||||
|
@ -1021,6 +984,59 @@ fn compile_load_operand<'ctx>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compile_load_place<'ctx>(
|
||||||
|
ctx: &ModuleCompileCtx<'ctx, '_>,
|
||||||
|
fn_id: DefId,
|
||||||
|
locals: &HashMap<usize, PointerValue<'ctx>>,
|
||||||
|
place: &ir::Place,
|
||||||
|
_is_copy: bool,
|
||||||
|
) -> Result<(BasicValueEnum<'ctx>, TypeInfo), BuilderError> {
|
||||||
|
let body = ctx.ctx.program.functions.get(&fn_id).unwrap();
|
||||||
|
let mut ptr = *locals.get(&place.local).unwrap();
|
||||||
|
let mut local_ty = body.locals[place.local].ty.clone();
|
||||||
|
|
||||||
|
for proj in &place.projection {
|
||||||
|
match proj {
|
||||||
|
ir::PlaceElem::Deref => {
|
||||||
|
ptr = ctx
|
||||||
|
.builder
|
||||||
|
.build_load(compile_basic_type(ctx, &local_ty), ptr, "deref")?
|
||||||
|
.into_pointer_value();
|
||||||
|
local_ty = match local_ty.kind {
|
||||||
|
ir::TypeKind::Ptr(inner) => *inner,
|
||||||
|
ir::TypeKind::Ref(_, inner) => *inner,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ir::PlaceElem::Field { field_idx } => {
|
||||||
|
local_ty = match local_ty.kind {
|
||||||
|
ir::TypeKind::Struct(id) => {
|
||||||
|
let struct_body = ctx.ctx.program.structs.get(&id).unwrap();
|
||||||
|
let ty = struct_body.variants[*field_idx].ty.clone();
|
||||||
|
let field_name = struct_body.variants[*field_idx].name.clone();
|
||||||
|
ptr = ctx.builder.build_struct_gep(
|
||||||
|
compile_basic_type(ctx, &local_ty),
|
||||||
|
ptr,
|
||||||
|
(*field_idx).try_into().unwrap(),
|
||||||
|
&format!("ptr_field_{field_name}"),
|
||||||
|
)?;
|
||||||
|
ty
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ir::PlaceElem::Index { .. } => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let pointee_ty = compile_basic_type(ctx, &local_ty);
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
ctx.builder.build_load(pointee_ty, ptr, "")?,
|
||||||
|
body.locals[place.local].ty.clone(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
fn compile_value<'ctx>(
|
fn compile_value<'ctx>(
|
||||||
ctx: &ModuleCompileCtx<'ctx, '_>,
|
ctx: &ModuleCompileCtx<'ctx, '_>,
|
||||||
val: &ValueTree,
|
val: &ValueTree,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Based on a cfg
|
// Based on a cfg
|
||||||
|
|
||||||
use std::collections::{BTreeMap, HashSet};
|
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||||
|
|
||||||
use edlang_span::Span;
|
use edlang_span::Span;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
@ -94,6 +94,7 @@ pub struct AdtBody {
|
||||||
pub is_pub: bool,
|
pub is_pub: bool,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub variants: Vec<AdtVariant>,
|
pub variants: Vec<AdtVariant>,
|
||||||
|
pub name_to_idx: HashMap<String, usize>,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +360,7 @@ pub struct Place {
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum PlaceElem {
|
pub enum PlaceElem {
|
||||||
Deref,
|
Deref,
|
||||||
Field { field_idx: usize, type_info: usize },
|
Field { field_idx: usize },
|
||||||
Index { local: usize },
|
Index { local: usize },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,7 @@ fn lower_struct(mut ctx: BuildCtx, info: &ast::Struct, module_id: DefId) -> Buil
|
||||||
is_pub: true, // todo struct pub
|
is_pub: true, // todo struct pub
|
||||||
name: info.name.name.clone(),
|
name: info.name.name.clone(),
|
||||||
variants: Vec::new(),
|
variants: Vec::new(),
|
||||||
|
name_to_idx: Default::default(),
|
||||||
span: info.span,
|
span: info.span,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -113,6 +114,8 @@ fn lower_struct(mut ctx: BuildCtx, info: &ast::Struct, module_id: DefId) -> Buil
|
||||||
ty: lower_type(&ctx, &field.r#type, module_id),
|
ty: lower_type(&ctx, &field.r#type, module_id),
|
||||||
};
|
};
|
||||||
body.variants.push(variant);
|
body.variants.push(variant);
|
||||||
|
body.name_to_idx
|
||||||
|
.insert(field.name.name.clone(), body.variants.len() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.body.structs.insert(body.def_id, body);
|
ctx.body.structs.insert(body.def_id, body);
|
||||||
|
@ -418,21 +421,6 @@ fn lower_let(builder: &mut BodyBuilder, info: &ast::LetStmt) {
|
||||||
fn lower_assign(builder: &mut BodyBuilder, info: &ast::AssignStmt) {
|
fn lower_assign(builder: &mut BodyBuilder, info: &ast::AssignStmt) {
|
||||||
let (mut place, mut ty) = lower_path(builder, &info.name);
|
let (mut place, mut ty) = lower_path(builder, &info.name);
|
||||||
|
|
||||||
if let Some(PlaceElem::Deref) = place.projection.last() {
|
|
||||||
match &ty {
|
|
||||||
TypeKind::Ptr(inner) => {
|
|
||||||
ty = inner.kind.clone();
|
|
||||||
}
|
|
||||||
TypeKind::Ref(is_mut, inner) => {
|
|
||||||
if !is_mut {
|
|
||||||
panic!("trying to mutate non mut ref");
|
|
||||||
}
|
|
||||||
ty = inner.kind.clone();
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _ in 0..info.deref_times {
|
for _ in 0..info.deref_times {
|
||||||
match &ty {
|
match &ty {
|
||||||
TypeKind::Ptr(inner) => {
|
TypeKind::Ptr(inner) => {
|
||||||
|
@ -454,7 +442,7 @@ fn lower_assign(builder: &mut BodyBuilder, info: &ast::AssignStmt) {
|
||||||
builder.statements.push(Statement {
|
builder.statements.push(Statement {
|
||||||
span: Some(info.name.first.span),
|
span: Some(info.name.first.span),
|
||||||
kind: StatementKind::Assign(place, rvalue),
|
kind: StatementKind::Assign(place, rvalue),
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_expr_type(builder: &mut BodyBuilder, info: &ast::Expression) -> Option<TypeKind> {
|
fn find_expr_type(builder: &mut BodyBuilder, info: &ast::Expression) -> Option<TypeKind> {
|
||||||
|
@ -887,7 +875,6 @@ fn lower_value(
|
||||||
},
|
},
|
||||||
ast::ValueExpr::Str { value: _, span: _ } => todo!(),
|
ast::ValueExpr::Str { value: _, span: _ } => todo!(),
|
||||||
ast::ValueExpr::Path(info) => {
|
ast::ValueExpr::Path(info) => {
|
||||||
// add deref info to path
|
|
||||||
let (place, ty) = lower_path(builder, info);
|
let (place, ty) = lower_path(builder, info);
|
||||||
(Operand::Move(place), ty)
|
(Operand::Move(place), ty)
|
||||||
}
|
}
|
||||||
|
@ -922,13 +909,26 @@ fn lower_path(builder: &mut BodyBuilder, info: &ast::PathExpr) -> (ir::Place, Ty
|
||||||
.name_to_local
|
.name_to_local
|
||||||
.get(&info.first.name)
|
.get(&info.first.name)
|
||||||
.expect("local not found");
|
.expect("local not found");
|
||||||
let ty = builder.body.locals[local].ty.kind.clone();
|
|
||||||
|
|
||||||
let projection = Vec::new();
|
let mut ty = builder.body.locals[local].ty.kind.clone();
|
||||||
|
let mut projection = Vec::new();
|
||||||
|
|
||||||
for extra in &info.extra {
|
for extra in &info.extra {
|
||||||
match extra {
|
match extra {
|
||||||
ast::PathSegment::Field(_) => todo!(),
|
ast::PathSegment::Field(name) => {
|
||||||
|
// is while fine? auto deref
|
||||||
|
while let TypeKind::Ref(_, inner) = ty {
|
||||||
|
projection.push(PlaceElem::Deref);
|
||||||
|
ty = inner.kind;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let TypeKind::Struct(id) = ty {
|
||||||
|
let struct_body = builder.ctx.body.structs.get(&id).unwrap();
|
||||||
|
let idx = *struct_body.name_to_idx.get(&name.name).unwrap();
|
||||||
|
projection.push(PlaceElem::Field { field_idx: idx });
|
||||||
|
ty = struct_body.variants[idx].ty.kind.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
ast::PathSegment::Index { .. } => todo!(),
|
ast::PathSegment::Index { .. } => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -936,7 +936,7 @@ fn lower_path(builder: &mut BodyBuilder, info: &ast::PathExpr) -> (ir::Place, Ty
|
||||||
(
|
(
|
||||||
Place {
|
Place {
|
||||||
local,
|
local,
|
||||||
projection: projection.into(), // todo, field array deref
|
projection: projection.into(), // todo, array
|
||||||
},
|
},
|
||||||
ty,
|
ty,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue