mirror of
https://github.com/edg-l/edlang.git
synced 2024-11-09 09:38:24 +00:00
feat: more debug locations
This commit is contained in:
parent
1e7bb55d2d
commit
3992a57069
|
@ -50,10 +50,18 @@ pub struct Ident {
|
||||||
pub struct Type {
|
pub struct Type {
|
||||||
pub name: Ident,
|
pub name: Ident,
|
||||||
pub generics: Vec<Type>,
|
pub generics: Vec<Type>,
|
||||||
pub is_ref: Option<RefType>,
|
pub qualifiers: Vec<TypeQualifier>,
|
||||||
pub span: Span,
|
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)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct FnParam {
|
pub struct FnParam {
|
||||||
pub name: Ident,
|
pub name: Ident,
|
||||||
|
@ -61,12 +69,6 @@ pub struct FnParam {
|
||||||
pub span: Span,
|
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)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
pub body: Vec<Statement>,
|
pub body: Vec<Statement>,
|
||||||
|
|
|
@ -398,7 +398,7 @@ fn compile_fn(ctx: &ModuleCompileCtx, fn_id: DefId) -> Result<(), BuilderError>
|
||||||
.build_load(compile_basic_type(ctx, &local_ty), ptr, "deref")?
|
.build_load(compile_basic_type(ctx, &local_ty), ptr, "deref")?
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
local_ty = match local_ty.kind {
|
local_ty = match local_ty.kind {
|
||||||
ir::TypeKind::Ptr(inner) => *inner,
|
ir::TypeKind::Ptr(_, inner) => *inner,
|
||||||
ir::TypeKind::Ref(_, inner) => *inner,
|
ir::TypeKind::Ref(_, inner) => *inner,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -606,7 +606,7 @@ fn compile_bin_op<'ctx>(
|
||||||
let is_float = matches!(lhs_ty.kind, ir::TypeKind::Float(_));
|
let is_float = matches!(lhs_ty.kind, ir::TypeKind::Float(_));
|
||||||
let is_signed = matches!(lhs_ty.kind, ir::TypeKind::Int(_));
|
let is_signed = matches!(lhs_ty.kind, ir::TypeKind::Int(_));
|
||||||
|
|
||||||
Ok(match op {
|
let (result, ty) = match op {
|
||||||
ir::BinOp::Add => {
|
ir::BinOp::Add => {
|
||||||
let value = if is_float {
|
let value = if is_float {
|
||||||
ctx.builder
|
ctx.builder
|
||||||
|
@ -931,7 +931,9 @@ fn compile_bin_op<'ctx>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ir::BinOp::Offset => todo!(),
|
ir::BinOp::Offset => todo!(),
|
||||||
})
|
};
|
||||||
|
|
||||||
|
Ok((result, ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_rvalue<'ctx>(
|
fn compile_rvalue<'ctx>(
|
||||||
|
@ -941,8 +943,25 @@ fn compile_rvalue<'ctx>(
|
||||||
rvalue: &ir::RValue,
|
rvalue: &ir::RValue,
|
||||||
) -> Result<(BasicValueEnum<'ctx>, TypeInfo), BuilderError> {
|
) -> Result<(BasicValueEnum<'ctx>, TypeInfo), BuilderError> {
|
||||||
Ok(match rvalue {
|
Ok(match rvalue {
|
||||||
ir::RValue::Use(op) => compile_load_operand(ctx, fn_id, locals, op)?,
|
ir::RValue::Use(op, span) => {
|
||||||
ir::RValue::Ref(_mutable, op) => match op {
|
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::Copy(_) => todo!(),
|
||||||
ir::Operand::Move(place) => {
|
ir::Operand::Move(place) => {
|
||||||
let mut ptr = *locals.get(&place.local).unwrap();
|
let mut ptr = *locals.get(&place.local).unwrap();
|
||||||
|
@ -959,7 +978,7 @@ fn compile_rvalue<'ctx>(
|
||||||
.build_load(compile_basic_type(ctx, &local_ty), ptr, "deref")?
|
.build_load(compile_basic_type(ctx, &local_ty), ptr, "deref")?
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
local_ty = match local_ty.kind {
|
local_ty = match local_ty.kind {
|
||||||
ir::TypeKind::Ptr(inner) => *inner,
|
ir::TypeKind::Ptr(_, inner) => *inner,
|
||||||
ir::TypeKind::Ref(_, inner) => *inner,
|
ir::TypeKind::Ref(_, inner) => *inner,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -972,10 +991,29 @@ fn compile_rvalue<'ctx>(
|
||||||
(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::BinOp(op, lhs, rhs, span) => {
|
||||||
ir::RValue::UnOp(op, value) => compile_unary_op(ctx, fn_id, locals, *op, value)?,
|
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")?
|
.build_load(compile_basic_type(ctx, &local_ty), ptr, "deref")?
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
local_ty = match local_ty.kind {
|
local_ty = match local_ty.kind {
|
||||||
ir::TypeKind::Ptr(inner) => *inner,
|
ir::TypeKind::Ptr(_, inner) => *inner,
|
||||||
ir::TypeKind::Ref(_, inner) => *inner,
|
ir::TypeKind::Ref(_, inner) => *inner,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -1110,6 +1148,10 @@ fn compile_value<'ctx>(
|
||||||
.into_int_type()
|
.into_int_type()
|
||||||
.const_int((*x) as u64, false)
|
.const_int((*x) as u64, false)
|
||||||
.as_basic_value_enum(),
|
.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!(),
|
ValueTree::Branch(_) => todo!(),
|
||||||
})
|
})
|
||||||
|
@ -1178,7 +1220,7 @@ fn compile_basic_type<'ctx>(
|
||||||
ir::TypeKind::FnDef(_def_id, _generic_args) => {
|
ir::TypeKind::FnDef(_def_id, _generic_args) => {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
ir::TypeKind::Ptr(_pointee) => ctx
|
ir::TypeKind::Ptr(_is_mut, _pointee) => ctx
|
||||||
.ctx
|
.ctx
|
||||||
.context
|
.context
|
||||||
.ptr_sized_int_type(&ctx.target_data, None)
|
.ptr_sized_int_type(&ctx.target_data, None)
|
||||||
|
@ -1205,6 +1247,7 @@ fn compile_basic_type<'ctx>(
|
||||||
.struct_type(&fields, false)
|
.struct_type(&fields, false)
|
||||||
.as_basic_type_enum()
|
.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) => {
|
ir::TypeKind::FnDef(_def_id, _generic_args) => {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
ir::TypeKind::Ptr(pointee) => ctx
|
ir::TypeKind::Ptr(_is_mut, pointee) => ctx
|
||||||
.di_builder
|
.di_builder
|
||||||
.create_pointer_type(
|
.create_pointer_type(
|
||||||
&format!("ptr<{:?}>", pointee.kind),
|
&format!("*{:?}", pointee.kind),
|
||||||
compile_debug_type(ctx, pointee),
|
compile_debug_type(ctx, pointee),
|
||||||
(ctx.target_data.get_pointer_byte_size(None) * 8).into(),
|
(ctx.target_data.get_pointer_byte_size(None) * 8).into(),
|
||||||
ctx.target_data.get_pointer_byte_size(None),
|
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()
|
.as_type()
|
||||||
}
|
}
|
||||||
|
ir::TypeKind::Str => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,7 +222,8 @@ pub enum TypeKind {
|
||||||
Uint(UintTy),
|
Uint(UintTy),
|
||||||
Float(FloatTy),
|
Float(FloatTy),
|
||||||
FnDef(DefId, Vec<TypeInfo>), // The vec are generic types, not arg types
|
FnDef(DefId, Vec<TypeInfo>), // The vec are generic types, not arg types
|
||||||
Ptr(Box<TypeInfo>),
|
Str,
|
||||||
|
Ptr(bool, Box<TypeInfo>),
|
||||||
Ref(bool, Box<TypeInfo>),
|
Ref(bool, Box<TypeInfo>),
|
||||||
Struct(DefId), // todo, add generics
|
Struct(DefId), // todo, add generics
|
||||||
}
|
}
|
||||||
|
@ -259,9 +260,10 @@ impl TypeKind {
|
||||||
Self::Float(_) => todo!(),
|
Self::Float(_) => todo!(),
|
||||||
TypeKind::Unit => unreachable!(),
|
TypeKind::Unit => unreachable!(),
|
||||||
TypeKind::FnDef(_, _) => unreachable!(),
|
TypeKind::FnDef(_, _) => unreachable!(),
|
||||||
TypeKind::Ptr(_pointee) => todo!(),
|
TypeKind::Ptr(_, _pointee) => todo!(),
|
||||||
TypeKind::Ref(_, inner) => inner.kind.get_falsy_value(),
|
TypeKind::Ref(_, inner) => inner.kind.get_falsy_value(),
|
||||||
TypeKind::Struct(_) => todo!(),
|
TypeKind::Struct(_) => todo!(),
|
||||||
|
TypeKind::Str => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -329,6 +331,7 @@ impl ValueTree {
|
||||||
ConstValue::F32(_) => TypeKind::Float(FloatTy::F32),
|
ConstValue::F32(_) => TypeKind::Float(FloatTy::F32),
|
||||||
ConstValue::F64(_) => TypeKind::Float(FloatTy::F64),
|
ConstValue::F64(_) => TypeKind::Float(FloatTy::F64),
|
||||||
ConstValue::Char(_) => TypeKind::Char,
|
ConstValue::Char(_) => TypeKind::Char,
|
||||||
|
ConstValue::Isize(_) => TypeKind::Int(IntTy::Isize),
|
||||||
},
|
},
|
||||||
ValueTree::Branch(_) => todo!(),
|
ValueTree::Branch(_) => todo!(),
|
||||||
}
|
}
|
||||||
|
@ -337,11 +340,11 @@ impl ValueTree {
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum RValue {
|
pub enum RValue {
|
||||||
Use(Operand),
|
Use(Operand, Span),
|
||||||
Ref(bool, Operand),
|
Ref(bool, Operand, Span),
|
||||||
BinOp(BinOp, Operand, Operand),
|
BinOp(BinOp, Operand, Operand, Span),
|
||||||
LogicOp(LogicalOp, Operand, Operand),
|
LogicOp(LogicalOp, Operand, Operand, Span),
|
||||||
UnOp(UnOp, Operand),
|
UnOp(UnOp, Operand, Span),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -465,6 +468,7 @@ pub enum ConstValue {
|
||||||
I32(i32),
|
I32(i32),
|
||||||
I64(i64),
|
I64(i64),
|
||||||
I128(i128),
|
I128(i128),
|
||||||
|
Isize(isize),
|
||||||
U8(u8),
|
U8(u8),
|
||||||
U16(u16),
|
U16(u16),
|
||||||
U32(u32),
|
U32(u32),
|
||||||
|
|
|
@ -235,7 +235,7 @@ fn lower_while(builder: &mut BodyBuilder, info: &WhileStmt, ret_type: &TypeKind)
|
||||||
terminator_span: Some(info.block.span),
|
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 local = builder.add_temp_local(TypeKind::Bool);
|
||||||
let place = Place {
|
let place = Place {
|
||||||
|
@ -244,7 +244,7 @@ fn lower_while(builder: &mut BodyBuilder, info: &WhileStmt, ret_type: &TypeKind)
|
||||||
};
|
};
|
||||||
|
|
||||||
builder.statements.push(Statement {
|
builder.statements.push(Statement {
|
||||||
span: Some(info.span),
|
span: Some(disc_span),
|
||||||
kind: StatementKind::Assign(place.clone(), discriminator),
|
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) {
|
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 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 local = builder.add_temp_local(TypeKind::Bool);
|
||||||
let place = Place {
|
let place = Place {
|
||||||
|
@ -312,7 +312,7 @@ fn lower_if_stmt(builder: &mut BodyBuilder, info: &ast::IfStmt, ret_type: &TypeK
|
||||||
};
|
};
|
||||||
|
|
||||||
builder.statements.push(Statement {
|
builder.statements.push(Statement {
|
||||||
span: Some(info.span),
|
span: Some(cond_span),
|
||||||
kind: StatementKind::Assign(place.clone(), condition),
|
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) {
|
fn lower_let(builder: &mut BodyBuilder, info: &ast::LetStmt) {
|
||||||
let ty = lower_type(&builder.ctx, &info.r#type, builder.local_module);
|
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();
|
let local_idx = builder.name_to_local.get(&info.name.name).copied().unwrap();
|
||||||
builder.statements.push(Statement {
|
builder.statements.push(Statement {
|
||||||
span: Some(info.name.span),
|
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) {
|
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 {
|
for _ in 0..info.deref_times {
|
||||||
match &ty {
|
match &ty {
|
||||||
TypeKind::Ptr(inner) => {
|
TypeKind::Ptr(is_mut, inner) => {
|
||||||
|
if !is_mut {
|
||||||
|
panic!("trying to mutate non mut ptr");
|
||||||
|
}
|
||||||
ty = inner.kind.clone();
|
ty = inner.kind.clone();
|
||||||
}
|
}
|
||||||
TypeKind::Ref(is_mut, inner) => {
|
TypeKind::Ref(is_mut, inner) => {
|
||||||
|
@ -437,7 +440,7 @@ fn lower_assign(builder: &mut BodyBuilder, info: &ast::AssignStmt) {
|
||||||
place.projection.push(PlaceElem::Deref);
|
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 {
|
builder.statements.push(Statement {
|
||||||
span: Some(info.name.first.span),
|
span: Some(info.name.first.span),
|
||||||
|
@ -507,21 +510,37 @@ fn lower_expr(
|
||||||
builder: &mut BodyBuilder,
|
builder: &mut BodyBuilder,
|
||||||
info: &ast::Expression,
|
info: &ast::Expression,
|
||||||
type_hint: Option<&TypeKind>,
|
type_hint: Option<&TypeKind>,
|
||||||
) -> (ir::RValue, TypeKind) {
|
) -> (ir::RValue, TypeKind, Span) {
|
||||||
match info {
|
match info {
|
||||||
ast::Expression::Value(info) => {
|
ast::Expression::Value(info) => {
|
||||||
let (value, ty) = lower_value(builder, info, type_hint);
|
let (value, ty, span) = lower_value(builder, info, type_hint);
|
||||||
(ir::RValue::Use(value), ty)
|
(ir::RValue::Use(value, span), ty, span)
|
||||||
}
|
}
|
||||||
ast::Expression::FnCall(info) => {
|
ast::Expression::FnCall(info) => {
|
||||||
let (value, ty) = lower_fn_call(builder, info);
|
let (value, ty, span) = lower_fn_call(builder, info);
|
||||||
(ir::RValue::Use(value), ty)
|
(ir::RValue::Use(value, span), ty, span)
|
||||||
}
|
}
|
||||||
ast::Expression::Unary(_, _) => todo!(),
|
ast::Expression::Unary(_, _) => todo!(),
|
||||||
ast::Expression::Binary(lhs, op, rhs) => {
|
ast::Expression::Binary(lhs, op, rhs) => {
|
||||||
lower_binary_expr(builder, lhs, op, rhs, type_hint)
|
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) => {
|
ast::Expression::AsRef(inner, mutable) => {
|
||||||
let type_hint = match type_hint {
|
let type_hint = match type_hint {
|
||||||
Some(inner) => match inner {
|
Some(inner) => match inner {
|
||||||
|
@ -530,11 +549,11 @@ fn lower_expr(
|
||||||
},
|
},
|
||||||
None => None,
|
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.
|
// check if its a use directly, to avoid a temporary.
|
||||||
value = match value {
|
value = match value {
|
||||||
RValue::Use(op) => RValue::Ref(*mutable, op),
|
RValue::Use(op, _span) => RValue::Ref(*mutable, op, span),
|
||||||
value => {
|
value => {
|
||||||
let inner_local = builder.add_local(Local::temp(ty.clone()));
|
let inner_local = builder.add_local(Local::temp(ty.clone()));
|
||||||
let inner_place = Place {
|
let inner_place = Place {
|
||||||
|
@ -551,19 +570,19 @@ fn lower_expr(
|
||||||
span: None,
|
span: None,
|
||||||
kind: StatementKind::Assign(inner_place.clone(), value),
|
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(
|
let ty = TypeKind::Ref(
|
||||||
*mutable,
|
*mutable,
|
||||||
Box::new(TypeInfo {
|
Box::new(TypeInfo {
|
||||||
span: None,
|
span: Some(span),
|
||||||
kind: ty,
|
kind: ty,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
(value, ty)
|
(value, ty, span)
|
||||||
}
|
}
|
||||||
ast::Expression::StructInit(info) => {
|
ast::Expression::StructInit(info) => {
|
||||||
let id = *builder
|
let id = *builder
|
||||||
|
@ -595,11 +614,10 @@ fn lower_expr(
|
||||||
field_place
|
field_place
|
||||||
.projection
|
.projection
|
||||||
.push(PlaceElem::Field { field_idx: idx });
|
.push(PlaceElem::Field { field_idx: idx });
|
||||||
let span = value.span;
|
|
||||||
|
|
||||||
let variant = &struct_body.variants[idx].ty.kind;
|
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 {
|
builder.statements.push(Statement {
|
||||||
span: Some(span),
|
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,
|
op: &ast::BinaryOp,
|
||||||
rhs: &ast::Expression,
|
rhs: &ast::Expression,
|
||||||
type_hint: Option<&TypeKind>,
|
type_hint: Option<&TypeKind>,
|
||||||
) -> (ir::RValue, TypeKind) {
|
) -> (ir::RValue, TypeKind, Span) {
|
||||||
trace!("lowering binary op: {:?}", op);
|
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)
|
let ty = find_expr_type(builder, lhs)
|
||||||
.unwrap_or_else(|| find_expr_type(builder, rhs).expect("cant find type"));
|
.unwrap_or_else(|| find_expr_type(builder, rhs).expect("cant find type"));
|
||||||
lower_expr(builder, lhs, Some(&ty))
|
lower_expr(builder, lhs, Some(&ty))
|
||||||
} else {
|
} else {
|
||||||
lower_expr(builder, lhs, type_hint)
|
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());
|
let ty = find_expr_type(builder, rhs).unwrap_or(lhs_ty.clone());
|
||||||
lower_expr(builder, rhs, Some(&ty))
|
lower_expr(builder, rhs, Some(&ty))
|
||||||
} else {
|
} else {
|
||||||
|
@ -636,7 +654,7 @@ fn lower_binary_expr(
|
||||||
};
|
};
|
||||||
|
|
||||||
let lhs = match lhs {
|
let lhs = match lhs {
|
||||||
RValue::Use(op) => op,
|
RValue::Use(op, _span) => op,
|
||||||
lhs => {
|
lhs => {
|
||||||
let lhs_local = builder.add_local(Local::temp(lhs_ty.clone()));
|
let lhs_local = builder.add_local(Local::temp(lhs_ty.clone()));
|
||||||
let lhs_place = Place {
|
let lhs_place = Place {
|
||||||
|
@ -658,7 +676,7 @@ fn lower_binary_expr(
|
||||||
};
|
};
|
||||||
|
|
||||||
let rhs = match rhs {
|
let rhs = match rhs {
|
||||||
RValue::Use(op) => op,
|
RValue::Use(op, _span) => op,
|
||||||
rhs => {
|
rhs => {
|
||||||
let rhs_local = builder.add_local(Local::temp(rhs_ty.clone()));
|
let rhs_local = builder.add_local(Local::temp(rhs_ty.clone()));
|
||||||
let rhs_place = Place {
|
let rhs_place = Place {
|
||||||
|
@ -680,46 +698,50 @@ fn lower_binary_expr(
|
||||||
};
|
};
|
||||||
|
|
||||||
match op {
|
match op {
|
||||||
ast::BinaryOp::Arith(op, _) => (
|
ast::BinaryOp::Arith(op, span) => (
|
||||||
match op {
|
match op {
|
||||||
ast::ArithOp::Add => ir::RValue::BinOp(ir::BinOp::Add, 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),
|
ast::ArithOp::Sub => ir::RValue::BinOp(ir::BinOp::Sub, lhs, rhs, *span),
|
||||||
ast::ArithOp::Mul => ir::RValue::BinOp(ir::BinOp::Mul, lhs, rhs),
|
ast::ArithOp::Mul => ir::RValue::BinOp(ir::BinOp::Mul, lhs, rhs, *span),
|
||||||
ast::ArithOp::Div => ir::RValue::BinOp(ir::BinOp::Div, lhs, rhs),
|
ast::ArithOp::Div => ir::RValue::BinOp(ir::BinOp::Div, lhs, rhs, *span),
|
||||||
ast::ArithOp::Mod => ir::RValue::BinOp(ir::BinOp::Rem, lhs, rhs),
|
ast::ArithOp::Mod => ir::RValue::BinOp(ir::BinOp::Rem, lhs, rhs, *span),
|
||||||
},
|
},
|
||||||
lhs_ty,
|
lhs_ty,
|
||||||
|
*span,
|
||||||
),
|
),
|
||||||
ast::BinaryOp::Logic(op, _) => (
|
ast::BinaryOp::Logic(op, span) => (
|
||||||
match op {
|
match op {
|
||||||
ast::LogicOp::And => ir::RValue::LogicOp(ir::LogicalOp::And, 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),
|
ast::LogicOp::Or => ir::RValue::LogicOp(ir::LogicalOp::Or, lhs, rhs, *span),
|
||||||
},
|
},
|
||||||
TypeKind::Bool,
|
TypeKind::Bool,
|
||||||
|
*span,
|
||||||
),
|
),
|
||||||
ast::BinaryOp::Compare(op, _) => (
|
ast::BinaryOp::Compare(op, span) => (
|
||||||
match op {
|
match op {
|
||||||
ast::CmpOp::Eq => ir::RValue::BinOp(ir::BinOp::Eq, 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),
|
ast::CmpOp::NotEq => ir::RValue::BinOp(ir::BinOp::Ne, lhs, rhs, *span),
|
||||||
ast::CmpOp::Lt => ir::RValue::BinOp(ir::BinOp::Lt, lhs, rhs),
|
ast::CmpOp::Lt => ir::RValue::BinOp(ir::BinOp::Lt, lhs, rhs, *span),
|
||||||
ast::CmpOp::LtEq => ir::RValue::BinOp(ir::BinOp::Le, lhs, rhs),
|
ast::CmpOp::LtEq => ir::RValue::BinOp(ir::BinOp::Le, lhs, rhs, *span),
|
||||||
ast::CmpOp::Gt => ir::RValue::BinOp(ir::BinOp::Gt, lhs, rhs),
|
ast::CmpOp::Gt => ir::RValue::BinOp(ir::BinOp::Gt, lhs, rhs, *span),
|
||||||
ast::CmpOp::GtEq => ir::RValue::BinOp(ir::BinOp::Ge, lhs, rhs),
|
ast::CmpOp::GtEq => ir::RValue::BinOp(ir::BinOp::Ge, lhs, rhs, *span),
|
||||||
},
|
},
|
||||||
TypeKind::Bool,
|
TypeKind::Bool,
|
||||||
|
*span,
|
||||||
),
|
),
|
||||||
ast::BinaryOp::Bitwise(op, _) => (
|
ast::BinaryOp::Bitwise(op, span) => (
|
||||||
match op {
|
match op {
|
||||||
ast::BitwiseOp::And => ir::RValue::BinOp(ir::BinOp::BitAnd, 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),
|
ast::BitwiseOp::Or => ir::RValue::BinOp(ir::BinOp::BitOr, lhs, rhs, *span),
|
||||||
ast::BitwiseOp::Xor => ir::RValue::BinOp(ir::BinOp::BitXor, lhs, rhs),
|
ast::BitwiseOp::Xor => ir::RValue::BinOp(ir::BinOp::BitXor, lhs, rhs, *span),
|
||||||
},
|
},
|
||||||
lhs_ty,
|
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 fn_id = {
|
||||||
let mod_body = builder.get_module_body();
|
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();
|
let mut args = Vec::new();
|
||||||
|
|
||||||
for (arg, arg_ty) in info.params.iter().zip(args_ty) {
|
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);
|
args.push(rvalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -793,14 +815,14 @@ fn lower_fn_call(builder: &mut BodyBuilder, info: &ast::FnCallExpr) -> (Operand,
|
||||||
terminator_span: Some(info.span),
|
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(
|
fn lower_value(
|
||||||
builder: &mut BodyBuilder,
|
builder: &mut BodyBuilder,
|
||||||
info: &ast::ValueExpr,
|
info: &ast::ValueExpr,
|
||||||
type_hint: Option<&TypeKind>,
|
type_hint: Option<&TypeKind>,
|
||||||
) -> (Operand, TypeKind) {
|
) -> (Operand, TypeKind, Span) {
|
||||||
match info {
|
match info {
|
||||||
ast::ValueExpr::Bool { value, span } => (
|
ast::ValueExpr::Bool { value, span } => (
|
||||||
ir::Operand::Constant(ir::ConstData {
|
ir::Operand::Constant(ir::ConstData {
|
||||||
|
@ -812,6 +834,7 @@ fn lower_value(
|
||||||
kind: ir::ConstKind::Value(ir::ValueTree::Leaf(ir::ConstValue::Bool(*value))),
|
kind: ir::ConstKind::Value(ir::ValueTree::Leaf(ir::ConstValue::Bool(*value))),
|
||||||
}),
|
}),
|
||||||
TypeKind::Bool,
|
TypeKind::Bool,
|
||||||
|
*span,
|
||||||
),
|
),
|
||||||
ast::ValueExpr::Char { value, span } => (
|
ast::ValueExpr::Char { value, span } => (
|
||||||
ir::Operand::Constant(ir::ConstData {
|
ir::Operand::Constant(ir::ConstData {
|
||||||
|
@ -825,6 +848,7 @@ fn lower_value(
|
||||||
))),
|
))),
|
||||||
}),
|
}),
|
||||||
TypeKind::Char,
|
TypeKind::Char,
|
||||||
|
*span,
|
||||||
),
|
),
|
||||||
ast::ValueExpr::Int { value, span } => {
|
ast::ValueExpr::Int { value, span } => {
|
||||||
let (ty, val) = match type_hint {
|
let (ty, val) = match type_hint {
|
||||||
|
@ -875,6 +899,10 @@ fn lower_value(
|
||||||
),
|
),
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
},
|
},
|
||||||
|
ir::TypeKind::Ptr(_, _) => (
|
||||||
|
ir::TypeKind::Int(ir::IntTy::Isize),
|
||||||
|
ir::ConstValue::Isize((*value) as isize),
|
||||||
|
),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
None => todo!(),
|
None => todo!(),
|
||||||
|
@ -890,6 +918,7 @@ fn lower_value(
|
||||||
kind: ir::ConstKind::Value(ir::ValueTree::Leaf(val)),
|
kind: ir::ConstKind::Value(ir::ValueTree::Leaf(val)),
|
||||||
}),
|
}),
|
||||||
ty,
|
ty,
|
||||||
|
*span,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ast::ValueExpr::Float { value, span } => match type_hint {
|
ast::ValueExpr::Float { value, span } => match type_hint {
|
||||||
|
@ -907,6 +936,7 @@ fn lower_value(
|
||||||
))),
|
))),
|
||||||
}),
|
}),
|
||||||
type_hint.clone(),
|
type_hint.clone(),
|
||||||
|
*span,
|
||||||
),
|
),
|
||||||
ir::FloatTy::F64 => (
|
ir::FloatTy::F64 => (
|
||||||
ir::Operand::Constant(ir::ConstData {
|
ir::Operand::Constant(ir::ConstData {
|
||||||
|
@ -920,6 +950,7 @@ fn lower_value(
|
||||||
))),
|
))),
|
||||||
}),
|
}),
|
||||||
type_hint.clone(),
|
type_hint.clone(),
|
||||||
|
*span,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
@ -928,17 +959,17 @@ fn lower_value(
|
||||||
},
|
},
|
||||||
ast::ValueExpr::Str { value: _, span: _ } => todo!(),
|
ast::ValueExpr::Str { value: _, span: _ } => todo!(),
|
||||||
ast::ValueExpr::Path(info) => {
|
ast::ValueExpr::Path(info) => {
|
||||||
let (place, ty) = lower_path(builder, info);
|
let (place, ty, span) = lower_path(builder, info);
|
||||||
(Operand::Move(place), ty)
|
(Operand::Move(place), ty, span)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_return(builder: &mut BodyBuilder, info: &ast::ReturnStmt, return_type: &TypeKind) {
|
fn lower_return(builder: &mut BodyBuilder, info: &ast::ReturnStmt, return_type: &TypeKind) {
|
||||||
if let Some(value_expr) = &info.value {
|
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 {
|
builder.statements.push(Statement {
|
||||||
span: Some(info.span),
|
span: Some(span),
|
||||||
kind: StatementKind::Assign(
|
kind: StatementKind::Assign(
|
||||||
Place {
|
Place {
|
||||||
local: builder.ret_local,
|
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
|
let local = *builder
|
||||||
.name_to_local
|
.name_to_local
|
||||||
.get(&info.first.name)
|
.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
|
projection: projection.into(), // todo, array
|
||||||
},
|
},
|
||||||
ty,
|
ty,
|
||||||
|
info.span,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::only_used_in_recursion)]
|
#[allow(clippy::only_used_in_recursion)]
|
||||||
pub fn lower_type(ctx: &BuildCtx, t: &ast::Type, module_id: DefId) -> ir::TypeInfo {
|
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 {
|
"()" => ir::TypeInfo {
|
||||||
span: Some(t.span),
|
span: Some(t.span),
|
||||||
kind: ir::TypeKind::Unit,
|
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),
|
span: Some(t.span),
|
||||||
kind: ir::TypeKind::Bool,
|
kind: ir::TypeKind::Bool,
|
||||||
},
|
},
|
||||||
"ptr" => ir::TypeInfo {
|
"str" => ir::TypeInfo {
|
||||||
span: Some(t.span),
|
span: Some(t.span),
|
||||||
kind: ir::TypeKind::Ptr(Box::new(lower_type(
|
kind: ir::TypeKind::Str,
|
||||||
ctx,
|
|
||||||
t.generics.first().unwrap(),
|
|
||||||
module_id,
|
|
||||||
))),
|
|
||||||
},
|
},
|
||||||
other => {
|
other => {
|
||||||
let module = ctx.body.modules.get(&module_id).expect("module not found");
|
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 {
|
for qualifier in &t.qualifiers {
|
||||||
Some(x) => ir::TypeInfo {
|
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),
|
span: Some(t.span),
|
||||||
kind: TypeKind::Ref(
|
kind,
|
||||||
match x {
|
};
|
||||||
ast::RefType::Not => false,
|
|
||||||
ast::RefType::Mut => true,
|
|
||||||
},
|
|
||||||
Box::new(inner_ty),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
None => inner_ty,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ty
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 = {
|
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,
|
name,
|
||||||
generics: vec![],
|
generics: vec![],
|
||||||
is_ref,
|
qualifiers,
|
||||||
span: ast::Span::new(lo, hi),
|
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,
|
name,
|
||||||
generics,
|
generics,
|
||||||
is_ref,
|
qualifiers,
|
||||||
span: ast::Span::new(lo, hi),
|
span: ast::Span::new(lo, hi),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -160,13 +167,13 @@ pub(crate) IdentWithOptionalType: ast::Type = {
|
||||||
<lo:@L> <name:Ident> <hi:@R> => ast::Type {
|
<lo:@L> <name:Ident> <hi:@R> => ast::Type {
|
||||||
name,
|
name,
|
||||||
generics: vec![],
|
generics: vec![],
|
||||||
is_ref: None,
|
qualifiers: vec![],
|
||||||
span: ast::Span::new(lo, hi),
|
span: ast::Span::new(lo, hi),
|
||||||
},
|
},
|
||||||
<lo:@L> <name:Ident> "::" "<" <generics:Comma<Type>> ">" <hi:@R> => ast::Type {
|
<lo:@L> <name:Ident> "::" "<" <generics:Comma<Type>> ">" <hi:@R> => ast::Type {
|
||||||
name,
|
name,
|
||||||
generics,
|
generics,
|
||||||
is_ref: None,
|
qualifiers: vec![],
|
||||||
span: ast::Span::new(lo, hi),
|
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 = {
|
pub(crate) FnParam: ast::FnParam = {
|
||||||
<lo:@L> <name:Ident> ":" <arg_type:Type> <hi:@R> => ast::FnParam {
|
<lo:@L> <name:Ident> ":" <arg_type:Type> <hi:@R> => ast::FnParam {
|
||||||
name,
|
name,
|
||||||
|
|
Loading…
Reference in a new issue