feat: more debug locations

This commit is contained in:
Edgar 2024-02-24 10:57:29 +01:00
parent 1e7bb55d2d
commit 3992a57069
No known key found for this signature in database
GPG key ID: 70ADAE8F35904387
5 changed files with 217 additions and 135 deletions

View file

@ -50,10 +50,18 @@ pub struct Ident {
pub struct Type {
pub name: Ident,
pub generics: Vec<Type>,
pub is_ref: Option<RefType>,
pub qualifiers: Vec<TypeQualifier>,
pub span: Span,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum TypeQualifier {
Ref, // &
RefMut, // &mut
Ptr, // *const
PtrMut, // *mut
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct FnParam {
pub name: Ident,
@ -61,12 +69,6 @@ pub struct FnParam {
pub span: Span,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum RefType {
Not,
Mut,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Block {
pub body: Vec<Statement>,

View file

@ -398,7 +398,7 @@ fn compile_fn(ctx: &ModuleCompileCtx, fn_id: DefId) -> Result<(), BuilderError>
.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::Ptr(_, inner) => *inner,
ir::TypeKind::Ref(_, inner) => *inner,
_ => unreachable!(),
}
@ -606,7 +606,7 @@ fn compile_bin_op<'ctx>(
let is_float = matches!(lhs_ty.kind, ir::TypeKind::Float(_));
let is_signed = matches!(lhs_ty.kind, ir::TypeKind::Int(_));
Ok(match op {
let (result, ty) = match op {
ir::BinOp::Add => {
let value = if is_float {
ctx.builder
@ -931,7 +931,9 @@ fn compile_bin_op<'ctx>(
)
}
ir::BinOp::Offset => todo!(),
})
};
Ok((result, ty))
}
fn compile_rvalue<'ctx>(
@ -941,41 +943,77 @@ fn compile_rvalue<'ctx>(
rvalue: &ir::RValue,
) -> Result<(BasicValueEnum<'ctx>, TypeInfo), BuilderError> {
Ok(match rvalue {
ir::RValue::Use(op) => compile_load_operand(ctx, fn_id, locals, op)?,
ir::RValue::Ref(_mutable, op) => match op {
ir::Operand::Copy(_) => todo!(),
ir::Operand::Move(place) => {
let mut ptr = *locals.get(&place.local).unwrap();
let mut local_ty = {
let body = ctx.ctx.program.functions.get(&fn_id).unwrap();
body.locals[place.local].ty.clone()
};
ir::RValue::Use(op, span) => {
ctx.set_debug_loc(
ctx.builder
.get_current_debug_location()
.unwrap()
.get_scope(),
*span,
);
compile_load_operand(ctx, fn_id, locals, op)?
}
ir::RValue::Ref(_mutable, op, span) => {
ctx.set_debug_loc(
ctx.builder
.get_current_debug_location()
.unwrap()
.get_scope(),
*span,
);
match op {
ir::Operand::Copy(_) => todo!(),
ir::Operand::Move(place) => {
let mut ptr = *locals.get(&place.local).unwrap();
let mut local_ty = {
let body = ctx.ctx.program.functions.get(&fn_id).unwrap();
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!(),
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!(),
}
ir::PlaceElem::Field { .. } => todo!(),
ir::PlaceElem::Index { .. } => todo!(),
}
}
(ptr.as_basic_value_enum(), local_ty)
(ptr.as_basic_value_enum(), local_ty)
}
ir::Operand::Constant(_) => todo!("references to constants not yet implemented"),
}
ir::Operand::Constant(_) => todo!("references to constants not yet implemented"),
},
ir::RValue::BinOp(op, lhs, rhs) => compile_bin_op(ctx, fn_id, locals, *op, lhs, rhs)?,
ir::RValue::LogicOp(_, _, _) => todo!(),
ir::RValue::UnOp(op, value) => compile_unary_op(ctx, fn_id, locals, *op, value)?,
}
ir::RValue::BinOp(op, lhs, rhs, span) => {
ctx.set_debug_loc(
ctx.builder
.get_current_debug_location()
.unwrap()
.get_scope(),
*span,
);
compile_bin_op(ctx, fn_id, locals, *op, lhs, rhs)?
}
ir::RValue::LogicOp(_, _, _, _span) => todo!(),
ir::RValue::UnOp(op, value, span) => {
ctx.set_debug_loc(
ctx.builder
.get_current_debug_location()
.unwrap()
.get_scope(),
*span,
);
compile_unary_op(ctx, fn_id, locals, *op, value)?
}
})
}
@ -1017,7 +1055,7 @@ fn compile_load_place<'ctx>(
.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::Ptr(_, inner) => *inner,
ir::TypeKind::Ref(_, inner) => *inner,
_ => unreachable!(),
}
@ -1110,6 +1148,10 @@ fn compile_value<'ctx>(
.into_int_type()
.const_int((*x) as u64, false)
.as_basic_value_enum(),
ir::ConstValue::Isize(x) => ty
.into_int_type()
.const_int((*x) as u64, true)
.as_basic_value_enum(),
},
ValueTree::Branch(_) => todo!(),
})
@ -1178,7 +1220,7 @@ fn compile_basic_type<'ctx>(
ir::TypeKind::FnDef(_def_id, _generic_args) => {
panic!()
}
ir::TypeKind::Ptr(_pointee) => ctx
ir::TypeKind::Ptr(_is_mut, _pointee) => ctx
.ctx
.context
.ptr_sized_int_type(&ctx.target_data, None)
@ -1205,6 +1247,7 @@ fn compile_basic_type<'ctx>(
.struct_type(&fields, false)
.as_basic_type_enum()
}
ir::TypeKind::Str => todo!(),
}
}
@ -1308,10 +1351,10 @@ fn compile_debug_type<'ctx>(ctx: &ModuleCompileCtx<'ctx, '_>, ty: &ir::TypeInfo)
ir::TypeKind::FnDef(_def_id, _generic_args) => {
panic!()
}
ir::TypeKind::Ptr(pointee) => ctx
ir::TypeKind::Ptr(_is_mut, pointee) => ctx
.di_builder
.create_pointer_type(
&format!("ptr<{:?}>", pointee.kind),
&format!("*{:?}", pointee.kind),
compile_debug_type(ctx, pointee),
(ctx.target_data.get_pointer_byte_size(None) * 8).into(),
ctx.target_data.get_pointer_byte_size(None),
@ -1357,5 +1400,6 @@ fn compile_debug_type<'ctx>(ctx: &ModuleCompileCtx<'ctx, '_>, ty: &ir::TypeInfo)
)
.as_type()
}
ir::TypeKind::Str => todo!(),
}
}

View file

@ -222,7 +222,8 @@ pub enum TypeKind {
Uint(UintTy),
Float(FloatTy),
FnDef(DefId, Vec<TypeInfo>), // The vec are generic types, not arg types
Ptr(Box<TypeInfo>),
Str,
Ptr(bool, Box<TypeInfo>),
Ref(bool, Box<TypeInfo>),
Struct(DefId), // todo, add generics
}
@ -259,9 +260,10 @@ impl TypeKind {
Self::Float(_) => todo!(),
TypeKind::Unit => unreachable!(),
TypeKind::FnDef(_, _) => unreachable!(),
TypeKind::Ptr(_pointee) => todo!(),
TypeKind::Ptr(_, _pointee) => todo!(),
TypeKind::Ref(_, inner) => inner.kind.get_falsy_value(),
TypeKind::Struct(_) => todo!(),
TypeKind::Str => todo!(),
}
}
}
@ -329,6 +331,7 @@ impl ValueTree {
ConstValue::F32(_) => TypeKind::Float(FloatTy::F32),
ConstValue::F64(_) => TypeKind::Float(FloatTy::F64),
ConstValue::Char(_) => TypeKind::Char,
ConstValue::Isize(_) => TypeKind::Int(IntTy::Isize),
},
ValueTree::Branch(_) => todo!(),
}
@ -337,11 +340,11 @@ impl ValueTree {
#[derive(Debug, Clone)]
pub enum RValue {
Use(Operand),
Ref(bool, Operand),
BinOp(BinOp, Operand, Operand),
LogicOp(LogicalOp, Operand, Operand),
UnOp(UnOp, Operand),
Use(Operand, Span),
Ref(bool, Operand, Span),
BinOp(BinOp, Operand, Operand, Span),
LogicOp(LogicalOp, Operand, Operand, Span),
UnOp(UnOp, Operand, Span),
}
#[derive(Debug, Clone)]
@ -465,6 +468,7 @@ pub enum ConstValue {
I32(i32),
I64(i64),
I128(i128),
Isize(isize),
U8(u8),
U16(u16),
U32(u32),

View file

@ -235,7 +235,7 @@ fn lower_while(builder: &mut BodyBuilder, info: &WhileStmt, ret_type: &TypeKind)
terminator_span: Some(info.block.span),
});
let (discriminator, discriminator_type) = lower_expr(builder, &info.condition, None);
let (discriminator, discriminator_type, disc_span) = lower_expr(builder, &info.condition, None);
let local = builder.add_temp_local(TypeKind::Bool);
let place = Place {
@ -244,7 +244,7 @@ fn lower_while(builder: &mut BodyBuilder, info: &WhileStmt, ret_type: &TypeKind)
};
builder.statements.push(Statement {
span: Some(info.span),
span: Some(disc_span),
kind: StatementKind::Assign(place.clone(), discriminator),
});
@ -303,7 +303,7 @@ fn lower_while(builder: &mut BodyBuilder, info: &WhileStmt, ret_type: &TypeKind)
fn lower_if_stmt(builder: &mut BodyBuilder, info: &ast::IfStmt, ret_type: &TypeKind) {
let cond_ty = find_expr_type(builder, &info.condition).expect("coouldnt find cond type");
let (condition, condition_ty) = lower_expr(builder, &info.condition, Some(&cond_ty));
let (condition, condition_ty, cond_span) = lower_expr(builder, &info.condition, Some(&cond_ty));
let local = builder.add_temp_local(TypeKind::Bool);
let place = Place {
@ -312,7 +312,7 @@ fn lower_if_stmt(builder: &mut BodyBuilder, info: &ast::IfStmt, ret_type: &TypeK
};
builder.statements.push(Statement {
span: Some(info.span),
span: Some(cond_span),
kind: StatementKind::Assign(place.clone(), condition),
});
@ -400,7 +400,7 @@ fn lower_if_stmt(builder: &mut BodyBuilder, info: &ast::IfStmt, ret_type: &TypeK
fn lower_let(builder: &mut BodyBuilder, info: &ast::LetStmt) {
let ty = lower_type(&builder.ctx, &info.r#type, builder.local_module);
let (rvalue, _ty) = lower_expr(builder, &info.value, Some(&ty.kind));
let (rvalue, _ty, _span) = lower_expr(builder, &info.value, Some(&ty.kind));
let local_idx = builder.name_to_local.get(&info.name.name).copied().unwrap();
builder.statements.push(Statement {
span: Some(info.name.span),
@ -419,11 +419,14 @@ fn lower_let(builder: &mut BodyBuilder, info: &ast::LetStmt) {
}
fn lower_assign(builder: &mut BodyBuilder, info: &ast::AssignStmt) {
let (mut place, mut ty) = lower_path(builder, &info.name);
let (mut place, mut ty, _span) = lower_path(builder, &info.name);
for _ in 0..info.deref_times {
match &ty {
TypeKind::Ptr(inner) => {
TypeKind::Ptr(is_mut, inner) => {
if !is_mut {
panic!("trying to mutate non mut ptr");
}
ty = inner.kind.clone();
}
TypeKind::Ref(is_mut, inner) => {
@ -437,7 +440,7 @@ fn lower_assign(builder: &mut BodyBuilder, info: &ast::AssignStmt) {
place.projection.push(PlaceElem::Deref);
}
let (rvalue, _ty) = lower_expr(builder, &info.value, Some(&ty));
let (rvalue, _ty, _span) = lower_expr(builder, &info.value, Some(&ty));
builder.statements.push(Statement {
span: Some(info.name.first.span),
@ -507,21 +510,37 @@ fn lower_expr(
builder: &mut BodyBuilder,
info: &ast::Expression,
type_hint: Option<&TypeKind>,
) -> (ir::RValue, TypeKind) {
) -> (ir::RValue, TypeKind, Span) {
match info {
ast::Expression::Value(info) => {
let (value, ty) = lower_value(builder, info, type_hint);
(ir::RValue::Use(value), ty)
let (value, ty, span) = lower_value(builder, info, type_hint);
(ir::RValue::Use(value, span), ty, span)
}
ast::Expression::FnCall(info) => {
let (value, ty) = lower_fn_call(builder, info);
(ir::RValue::Use(value), ty)
let (value, ty, span) = lower_fn_call(builder, info);
(ir::RValue::Use(value, span), ty, span)
}
ast::Expression::Unary(_, _) => todo!(),
ast::Expression::Binary(lhs, op, rhs) => {
lower_binary_expr(builder, lhs, op, rhs, type_hint)
}
ast::Expression::Deref(_) => todo!(),
ast::Expression::Deref(inner) => {
let (value, ty, span) = lower_expr(builder, inner, type_hint);
// check if its a use directly, to avoid a temporary.
let mut value = match value {
RValue::Use(op, _) => match op {
Operand::Copy(place) => place,
Operand::Move(place) => place,
Operand::Constant(_) => todo!("constant data deref"),
},
_ => unreachable!(),
};
value.projection.push(PlaceElem::Deref);
(RValue::Use(Operand::Move(value), span), ty, span)
}
ast::Expression::AsRef(inner, mutable) => {
let type_hint = match type_hint {
Some(inner) => match inner {
@ -530,11 +549,11 @@ fn lower_expr(
},
None => None,
};
let (mut value, ty) = lower_expr(builder, inner, type_hint);
let (mut value, ty, span) = lower_expr(builder, inner, type_hint);
// check if its a use directly, to avoid a temporary.
value = match value {
RValue::Use(op) => RValue::Ref(*mutable, op),
RValue::Use(op, _span) => RValue::Ref(*mutable, op, span),
value => {
let inner_local = builder.add_local(Local::temp(ty.clone()));
let inner_place = Place {
@ -551,19 +570,19 @@ fn lower_expr(
span: None,
kind: StatementKind::Assign(inner_place.clone(), value),
});
RValue::Ref(*mutable, Operand::Move(inner_place))
RValue::Ref(*mutable, Operand::Move(inner_place), span)
}
};
let ty = TypeKind::Ref(
*mutable,
Box::new(TypeInfo {
span: None,
span: Some(span),
kind: ty,
}),
);
(value, ty)
(value, ty, span)
}
ast::Expression::StructInit(info) => {
let id = *builder
@ -595,11 +614,10 @@ fn lower_expr(
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));
let (value, _value_ty, span) = lower_expr(builder, &value.value, Some(variant));
builder.statements.push(Statement {
span: Some(span),
@ -607,7 +625,7 @@ fn lower_expr(
});
}
(RValue::Use(Operand::Move(place)), ty)
(RValue::Use(Operand::Move(place), info.span), ty, info.span)
}
}
}
@ -618,17 +636,17 @@ fn lower_binary_expr(
op: &ast::BinaryOp,
rhs: &ast::Expression,
type_hint: Option<&TypeKind>,
) -> (ir::RValue, TypeKind) {
) -> (ir::RValue, TypeKind, Span) {
trace!("lowering binary op: {:?}", op);
let (lhs, lhs_ty) = if type_hint.is_none() {
let (lhs, lhs_ty, _) = if type_hint.is_none() {
let ty = find_expr_type(builder, lhs)
.unwrap_or_else(|| find_expr_type(builder, rhs).expect("cant find type"));
lower_expr(builder, lhs, Some(&ty))
} else {
lower_expr(builder, lhs, type_hint)
};
let (rhs, rhs_ty) = if type_hint.is_none() {
let (rhs, rhs_ty, _) = if type_hint.is_none() {
let ty = find_expr_type(builder, rhs).unwrap_or(lhs_ty.clone());
lower_expr(builder, rhs, Some(&ty))
} else {
@ -636,7 +654,7 @@ fn lower_binary_expr(
};
let lhs = match lhs {
RValue::Use(op) => op,
RValue::Use(op, _span) => op,
lhs => {
let lhs_local = builder.add_local(Local::temp(lhs_ty.clone()));
let lhs_place = Place {
@ -658,7 +676,7 @@ fn lower_binary_expr(
};
let rhs = match rhs {
RValue::Use(op) => op,
RValue::Use(op, _span) => op,
rhs => {
let rhs_local = builder.add_local(Local::temp(rhs_ty.clone()));
let rhs_place = Place {
@ -680,46 +698,50 @@ fn lower_binary_expr(
};
match op {
ast::BinaryOp::Arith(op, _) => (
ast::BinaryOp::Arith(op, span) => (
match op {
ast::ArithOp::Add => ir::RValue::BinOp(ir::BinOp::Add, lhs, rhs),
ast::ArithOp::Sub => ir::RValue::BinOp(ir::BinOp::Sub, lhs, rhs),
ast::ArithOp::Mul => ir::RValue::BinOp(ir::BinOp::Mul, lhs, rhs),
ast::ArithOp::Div => ir::RValue::BinOp(ir::BinOp::Div, lhs, rhs),
ast::ArithOp::Mod => ir::RValue::BinOp(ir::BinOp::Rem, lhs, rhs),
ast::ArithOp::Add => ir::RValue::BinOp(ir::BinOp::Add, lhs, rhs, *span),
ast::ArithOp::Sub => ir::RValue::BinOp(ir::BinOp::Sub, lhs, rhs, *span),
ast::ArithOp::Mul => ir::RValue::BinOp(ir::BinOp::Mul, lhs, rhs, *span),
ast::ArithOp::Div => ir::RValue::BinOp(ir::BinOp::Div, lhs, rhs, *span),
ast::ArithOp::Mod => ir::RValue::BinOp(ir::BinOp::Rem, lhs, rhs, *span),
},
lhs_ty,
*span,
),
ast::BinaryOp::Logic(op, _) => (
ast::BinaryOp::Logic(op, span) => (
match op {
ast::LogicOp::And => ir::RValue::LogicOp(ir::LogicalOp::And, lhs, rhs),
ast::LogicOp::Or => ir::RValue::LogicOp(ir::LogicalOp::Or, lhs, rhs),
ast::LogicOp::And => ir::RValue::LogicOp(ir::LogicalOp::And, lhs, rhs, *span),
ast::LogicOp::Or => ir::RValue::LogicOp(ir::LogicalOp::Or, lhs, rhs, *span),
},
TypeKind::Bool,
*span,
),
ast::BinaryOp::Compare(op, _) => (
ast::BinaryOp::Compare(op, span) => (
match op {
ast::CmpOp::Eq => ir::RValue::BinOp(ir::BinOp::Eq, lhs, rhs),
ast::CmpOp::NotEq => ir::RValue::BinOp(ir::BinOp::Ne, lhs, rhs),
ast::CmpOp::Lt => ir::RValue::BinOp(ir::BinOp::Lt, lhs, rhs),
ast::CmpOp::LtEq => ir::RValue::BinOp(ir::BinOp::Le, lhs, rhs),
ast::CmpOp::Gt => ir::RValue::BinOp(ir::BinOp::Gt, lhs, rhs),
ast::CmpOp::GtEq => ir::RValue::BinOp(ir::BinOp::Ge, lhs, rhs),
ast::CmpOp::Eq => ir::RValue::BinOp(ir::BinOp::Eq, lhs, rhs, *span),
ast::CmpOp::NotEq => ir::RValue::BinOp(ir::BinOp::Ne, lhs, rhs, *span),
ast::CmpOp::Lt => ir::RValue::BinOp(ir::BinOp::Lt, lhs, rhs, *span),
ast::CmpOp::LtEq => ir::RValue::BinOp(ir::BinOp::Le, lhs, rhs, *span),
ast::CmpOp::Gt => ir::RValue::BinOp(ir::BinOp::Gt, lhs, rhs, *span),
ast::CmpOp::GtEq => ir::RValue::BinOp(ir::BinOp::Ge, lhs, rhs, *span),
},
TypeKind::Bool,
*span,
),
ast::BinaryOp::Bitwise(op, _) => (
ast::BinaryOp::Bitwise(op, span) => (
match op {
ast::BitwiseOp::And => ir::RValue::BinOp(ir::BinOp::BitAnd, lhs, rhs),
ast::BitwiseOp::Or => ir::RValue::BinOp(ir::BinOp::BitOr, lhs, rhs),
ast::BitwiseOp::Xor => ir::RValue::BinOp(ir::BinOp::BitXor, lhs, rhs),
ast::BitwiseOp::And => ir::RValue::BinOp(ir::BinOp::BitAnd, lhs, rhs, *span),
ast::BitwiseOp::Or => ir::RValue::BinOp(ir::BinOp::BitOr, lhs, rhs, *span),
ast::BitwiseOp::Xor => ir::RValue::BinOp(ir::BinOp::BitXor, lhs, rhs, *span),
},
lhs_ty,
*span,
),
}
}
fn lower_fn_call(builder: &mut BodyBuilder, info: &ast::FnCallExpr) -> (Operand, TypeKind) {
fn lower_fn_call(builder: &mut BodyBuilder, info: &ast::FnCallExpr) -> (Operand, TypeKind, Span) {
let fn_id = {
let mod_body = builder.get_module_body();
@ -765,7 +787,7 @@ fn lower_fn_call(builder: &mut BodyBuilder, info: &ast::FnCallExpr) -> (Operand,
let mut args = Vec::new();
for (arg, arg_ty) in info.params.iter().zip(args_ty) {
let (rvalue, _rvalue_ty) = lower_expr(builder, arg, Some(&arg_ty.kind));
let (rvalue, _rvalue_ty, _span) = lower_expr(builder, arg, Some(&arg_ty.kind));
args.push(rvalue);
}
@ -793,14 +815,14 @@ fn lower_fn_call(builder: &mut BodyBuilder, info: &ast::FnCallExpr) -> (Operand,
terminator_span: Some(info.span),
});
(Operand::Move(dest_place), ret_ty.kind.clone())
(Operand::Move(dest_place), ret_ty.kind.clone(), info.span)
}
fn lower_value(
builder: &mut BodyBuilder,
info: &ast::ValueExpr,
type_hint: Option<&TypeKind>,
) -> (Operand, TypeKind) {
) -> (Operand, TypeKind, Span) {
match info {
ast::ValueExpr::Bool { value, span } => (
ir::Operand::Constant(ir::ConstData {
@ -812,6 +834,7 @@ fn lower_value(
kind: ir::ConstKind::Value(ir::ValueTree::Leaf(ir::ConstValue::Bool(*value))),
}),
TypeKind::Bool,
*span,
),
ast::ValueExpr::Char { value, span } => (
ir::Operand::Constant(ir::ConstData {
@ -825,6 +848,7 @@ fn lower_value(
))),
}),
TypeKind::Char,
*span,
),
ast::ValueExpr::Int { value, span } => {
let (ty, val) = match type_hint {
@ -875,6 +899,10 @@ fn lower_value(
),
_ => todo!(),
},
ir::TypeKind::Ptr(_, _) => (
ir::TypeKind::Int(ir::IntTy::Isize),
ir::ConstValue::Isize((*value) as isize),
),
_ => unreachable!(),
},
None => todo!(),
@ -890,6 +918,7 @@ fn lower_value(
kind: ir::ConstKind::Value(ir::ValueTree::Leaf(val)),
}),
ty,
*span,
)
}
ast::ValueExpr::Float { value, span } => match type_hint {
@ -907,6 +936,7 @@ fn lower_value(
))),
}),
type_hint.clone(),
*span,
),
ir::FloatTy::F64 => (
ir::Operand::Constant(ir::ConstData {
@ -920,6 +950,7 @@ fn lower_value(
))),
}),
type_hint.clone(),
*span,
),
},
_ => unreachable!(),
@ -928,17 +959,17 @@ fn lower_value(
},
ast::ValueExpr::Str { value: _, span: _ } => todo!(),
ast::ValueExpr::Path(info) => {
let (place, ty) = lower_path(builder, info);
(Operand::Move(place), ty)
let (place, ty, span) = lower_path(builder, info);
(Operand::Move(place), ty, span)
}
}
}
fn lower_return(builder: &mut BodyBuilder, info: &ast::ReturnStmt, return_type: &TypeKind) {
if let Some(value_expr) = &info.value {
let (value, _ty) = lower_expr(builder, value_expr, Some(return_type));
let (value, _ty, span) = lower_expr(builder, value_expr, Some(return_type));
builder.statements.push(Statement {
span: Some(info.span),
span: Some(span),
kind: StatementKind::Assign(
Place {
local: builder.ret_local,
@ -957,7 +988,7 @@ fn lower_return(builder: &mut BodyBuilder, info: &ast::ReturnStmt, return_type:
});
}
fn lower_path(builder: &mut BodyBuilder, info: &ast::PathExpr) -> (ir::Place, TypeKind) {
fn lower_path(builder: &mut BodyBuilder, info: &ast::PathExpr) -> (ir::Place, TypeKind, Span) {
let local = *builder
.name_to_local
.get(&info.first.name)
@ -992,12 +1023,13 @@ fn lower_path(builder: &mut BodyBuilder, info: &ast::PathExpr) -> (ir::Place, Ty
projection: projection.into(), // todo, array
},
ty,
info.span,
)
}
#[allow(clippy::only_used_in_recursion)]
pub fn lower_type(ctx: &BuildCtx, t: &ast::Type, module_id: DefId) -> ir::TypeInfo {
let inner_ty = match t.name.name.as_str() {
let mut ty = match t.name.name.as_str() {
"()" => ir::TypeInfo {
span: Some(t.span),
kind: ir::TypeKind::Unit,
@ -1050,13 +1082,9 @@ pub fn lower_type(ctx: &BuildCtx, t: &ast::Type, module_id: DefId) -> ir::TypeIn
span: Some(t.span),
kind: ir::TypeKind::Bool,
},
"ptr" => ir::TypeInfo {
"str" => ir::TypeInfo {
span: Some(t.span),
kind: ir::TypeKind::Ptr(Box::new(lower_type(
ctx,
t.generics.first().unwrap(),
module_id,
))),
kind: ir::TypeKind::Str,
},
other => {
let module = ctx.body.modules.get(&module_id).expect("module not found");
@ -1072,17 +1100,19 @@ pub fn lower_type(ctx: &BuildCtx, t: &ast::Type, module_id: DefId) -> ir::TypeIn
}
};
match t.is_ref {
Some(x) => ir::TypeInfo {
for qualifier in &t.qualifiers {
let kind = match qualifier {
ast::TypeQualifier::Ref => TypeKind::Ref(false, Box::new(ty)),
ast::TypeQualifier::RefMut => TypeKind::Ref(true, Box::new(ty)),
ast::TypeQualifier::Ptr => TypeKind::Ptr(false, Box::new(ty)),
ast::TypeQualifier::PtrMut => TypeKind::Ptr(true, Box::new(ty)),
};
ty = TypeInfo {
span: Some(t.span),
kind: TypeKind::Ref(
match x {
ast::RefType::Not => false,
ast::RefType::Mut => true,
},
Box::new(inner_ty),
),
},
None => inner_ty,
kind,
};
}
ty
}

View file

@ -140,17 +140,24 @@ pub(crate) Ident: ast::Ident = {
}
}
pub(crate) TypeQualifier: ast::TypeQualifier = {
"&" => ast::TypeQualifier::Ref,
"&" "mut" => ast::TypeQualifier::RefMut,
"*" "const" => ast::TypeQualifier::Ptr,
"*" "mut" => ast::TypeQualifier::PtrMut,
}
pub(crate) Type: ast::Type = {
<lo:@L> <is_ref:RefType?> <name:Ident> <hi:@R> => ast::Type {
<lo:@L> <qualifiers:TypeQualifier*> <name:Ident> <hi:@R> => ast::Type {
name,
generics: vec![],
is_ref,
qualifiers,
span: ast::Span::new(lo, hi),
},
<lo:@L> <is_ref:RefType?> <name:Ident> "<" <generics:Comma<Type>> ">" <hi:@R> => ast::Type {
<lo:@L> <qualifiers:TypeQualifier*> <name:Ident> "<" <generics:Comma<Type>> ">" <hi:@R> => ast::Type {
name,
generics,
is_ref,
qualifiers,
span: ast::Span::new(lo, hi),
},
}
@ -160,13 +167,13 @@ pub(crate) IdentWithOptionalType: ast::Type = {
<lo:@L> <name:Ident> <hi:@R> => ast::Type {
name,
generics: vec![],
is_ref: None,
qualifiers: vec![],
span: ast::Span::new(lo, hi),
},
<lo:@L> <name:Ident> "::" "<" <generics:Comma<Type>> ">" <hi:@R> => ast::Type {
name,
generics,
is_ref: None,
qualifiers: vec![],
span: ast::Span::new(lo, hi),
},
}
@ -404,11 +411,6 @@ pub(crate) StructInitExpr: ast::StructInitExpr = {
}
}
pub(crate) RefType: ast::RefType = {
"&" => ast::RefType::Not,
"&" "mut" => ast::RefType::Mut,
}
pub(crate) FnParam: ast::FnParam = {
<lo:@L> <name:Ident> ":" <arg_type:Type> <hi:@R> => ast::FnParam {
name,