From 3992a570698f01e6bf85a78bd87028379d068197 Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Sat, 24 Feb 2024 10:57:29 +0100 Subject: [PATCH] feat: more debug locations --- lib/edlang_ast/src/lib.rs | 16 ++- lib/edlang_codegen_llvm/src/codegen.rs | 116 +++++++++++----- lib/edlang_ir/src/lib.rs | 18 ++- lib/edlang_lowering/src/lib.rs | 178 +++++++++++++++---------- lib/edlang_parser/src/grammar.lalrpop | 24 ++-- 5 files changed, 217 insertions(+), 135 deletions(-) diff --git a/lib/edlang_ast/src/lib.rs b/lib/edlang_ast/src/lib.rs index 4597c58d8..cb62ee9ac 100644 --- a/lib/edlang_ast/src/lib.rs +++ b/lib/edlang_ast/src/lib.rs @@ -50,10 +50,18 @@ pub struct Ident { pub struct Type { pub name: Ident, pub generics: Vec, - pub is_ref: Option, + pub qualifiers: Vec, 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, diff --git a/lib/edlang_codegen_llvm/src/codegen.rs b/lib/edlang_codegen_llvm/src/codegen.rs index 3a9e1e232..50e6bdd4e 100644 --- a/lib/edlang_codegen_llvm/src/codegen.rs +++ b/lib/edlang_codegen_llvm/src/codegen.rs @@ -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!(), } } diff --git a/lib/edlang_ir/src/lib.rs b/lib/edlang_ir/src/lib.rs index 0b320c61d..9afa1d6af 100644 --- a/lib/edlang_ir/src/lib.rs +++ b/lib/edlang_ir/src/lib.rs @@ -222,7 +222,8 @@ pub enum TypeKind { Uint(UintTy), Float(FloatTy), FnDef(DefId, Vec), // The vec are generic types, not arg types - Ptr(Box), + Str, + Ptr(bool, Box), Ref(bool, Box), 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), diff --git a/lib/edlang_lowering/src/lib.rs b/lib/edlang_lowering/src/lib.rs index 259ca9c04..1c4abedf5 100644 --- a/lib/edlang_lowering/src/lib.rs +++ b/lib/edlang_lowering/src/lib.rs @@ -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 } diff --git a/lib/edlang_parser/src/grammar.lalrpop b/lib/edlang_parser/src/grammar.lalrpop index e9db9d974..2df97eeb4 100644 --- a/lib/edlang_parser/src/grammar.lalrpop +++ b/lib/edlang_parser/src/grammar.lalrpop @@ -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 = { - => ast::Type { + => ast::Type { name, generics: vec![], - is_ref, + qualifiers, span: ast::Span::new(lo, hi), }, - "<" > ">" => ast::Type { + "<" > ">" => ast::Type { name, generics, - is_ref, + qualifiers, span: ast::Span::new(lo, hi), }, } @@ -160,13 +167,13 @@ pub(crate) IdentWithOptionalType: ast::Type = { => ast::Type { name, generics: vec![], - is_ref: None, + qualifiers: vec![], span: ast::Span::new(lo, hi), }, "::" "<" > ">" => 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 = { ":" => ast::FnParam { name,