diff --git a/lib/edlang_ast/src/lib.rs b/lib/edlang_ast/src/lib.rs index ca1b512c6..ba9a6fd23 100644 --- a/lib/edlang_ast/src/lib.rs +++ b/lib/edlang_ast/src/lib.rs @@ -62,6 +62,7 @@ pub struct Ident { pub struct Type { pub name: Ident, pub generics: Vec, + pub is_ref: Option, pub span: Span, } @@ -72,6 +73,12 @@ 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 c01dedf88..9f24a7ed7 100644 --- a/lib/edlang_codegen_llvm/src/codegen.rs +++ b/lib/edlang_codegen_llvm/src/codegen.rs @@ -18,7 +18,7 @@ use inkwell::{ AddressSpace, }; use ir::{LocalKind, ModuleBody, ProgramBody, TypeInfo, ValueTree}; -use llvm_sys::debuginfo::LLVMDIFlagPublic; +use llvm_sys::debuginfo::{LLVMDIFlagLValueReference, LLVMDIFlagPublic}; use tracing::{info, trace}; #[derive(Debug, Clone, Copy)] @@ -1083,6 +1083,12 @@ fn compile_basic_type<'ctx>( .ptr_sized_int_type(&ctx.target_data, None) .ptr_type(AddressSpace::default()) .as_basic_type_enum(), + ir::TypeKind::Ref(_, _) => ctx + .ctx + .context + .ptr_sized_int_type(&ctx.target_data, None) + .ptr_type(AddressSpace::default()) + .as_basic_type_enum(), } } @@ -1093,6 +1099,8 @@ fn compile_debug_type<'ctx>(ctx: &ModuleCompileCtx<'ctx, '_>, ty: &ir::TypeInfo) // 5 = signed // 11 = numeric string // https://dwarfstd.org/doc/DWARF5.pdf#section.7.8 + + // https://github.com/GaloisInc/dwarf-tools/blob/master/src/DWARF/DW/TAG.hs match &ty.kind { ir::TypeKind::Unit => todo!(), ir::TypeKind::Bool => ctx @@ -1194,5 +1202,9 @@ fn compile_debug_type<'ctx>(ctx: &ModuleCompileCtx<'ctx, '_>, ty: &ir::TypeInfo) AddressSpace::default(), ) .as_type(), + ir::TypeKind::Ref(_, inner) => ctx + .di_builder + .create_reference_type(compile_debug_type(ctx, inner), 0x10) + .as_type(), } } diff --git a/lib/edlang_ir/src/lib.rs b/lib/edlang_ir/src/lib.rs index 91fe5af2d..1bc3cfb06 100644 --- a/lib/edlang_ir/src/lib.rs +++ b/lib/edlang_ir/src/lib.rs @@ -204,6 +204,7 @@ pub enum TypeKind { Float(FloatTy), FnDef(DefId, Vec), // The vec are generic types, not arg types Ptr(Box), + Ref(bool, Box), } impl TypeKind { @@ -235,6 +236,7 @@ impl TypeKind { TypeKind::Unit => unreachable!(), TypeKind::FnDef(_, _) => unreachable!(), TypeKind::Ptr(_pointee) => todo!(), + TypeKind::Ref(_, inner) => inner.kind.get_falsy_value(), } } } diff --git a/lib/edlang_lowering/src/lib.rs b/lib/edlang_lowering/src/lib.rs index 1d3be6ba3..cbf91f6a3 100644 --- a/lib/edlang_lowering/src/lib.rs +++ b/lib/edlang_lowering/src/lib.rs @@ -802,7 +802,7 @@ fn lower_path(builder: &mut BodyBuilder, info: &ast::PathExpr) -> (ir::Place, Ty #[allow(clippy::only_used_in_recursion)] pub fn lower_type(ctx: &BuildCtx, t: &ast::Type) -> ir::TypeInfo { - match t.name.name.as_str() { + let inner_ty = match t.name.name.as_str() { "()" => ir::TypeInfo { span: Some(t.span), kind: ir::TypeKind::Unit, @@ -860,5 +860,19 @@ pub fn lower_type(ctx: &BuildCtx, t: &ast::Type) -> ir::TypeInfo { kind: ir::TypeKind::Ptr(Box::new(lower_type(ctx, t.generics.first().unwrap()))), }, x => todo!("{:?}", x), + }; + + match t.is_ref { + Some(x) => ir::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, } } diff --git a/lib/edlang_parser/src/grammar.lalrpop b/lib/edlang_parser/src/grammar.lalrpop index dcc75feed..429a84764 100644 --- a/lib/edlang_parser/src/grammar.lalrpop +++ b/lib/edlang_parser/src/grammar.lalrpop @@ -141,14 +141,16 @@ pub(crate) Ident: ast::Ident = { } pub(crate) Type: ast::Type = { - => ast::Type { + => ast::Type { name, generics: vec![], + is_ref, span: ast::Span::new(lo, hi), }, - "<" > ">" => ast::Type { + "<" > ">" => ast::Type { name, generics, + is_ref, span: ast::Span::new(lo, hi), }, } @@ -346,6 +348,11 @@ pub(crate) ValueExpr: ast::ValueExpr = { => ast::ValueExpr::Path(<>), } +pub(crate) RefType: ast::RefType = { + "&" => ast::RefType::Not, + "&" "mut" => ast::RefType::Mut, +} + pub(crate) FnParam: ast::FnParam = { ":" => ast::FnParam { name,