From b94c6a4e7d60002088a2f797221bee78fdae6650 Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Sun, 5 May 2024 15:09:24 +0200 Subject: [PATCH] codegen for impl methods --- Cargo.toml | 3 +- lib/edlang_ast/src/lib.rs | 1 + lib/edlang_ir/src/lib.rs | 1 + lib/edlang_lowering/src/lib.rs | 128 +++++++++++++++++++++++--- lib/edlang_parser/src/grammar.lalrpop | 4 + program | Bin 0 -> 15808 bytes 6 files changed, 125 insertions(+), 12 deletions(-) create mode 100755 program diff --git a/Cargo.toml b/Cargo.toml index 5d68cdcff..afa60c4fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,8 @@ [workspace] resolver = "2" -members = [ "bin/edlangc", "edb", "lib/edlang_ast", "lib/edlang_check", "lib/edlang_codegen_llvm", "lib/edlang_driver", "lib/edlang_ir", "lib/edlang_lowering","lib/edlang_parser", "lib/edlang_session", "lib/edlang_span"] +members = [ "bin/edlangc", "edb", "lib/edlang_ast", "lib/edlang_check", "lib/edlang_codegen_llvm", +"lib/edlang_driver", "lib/edlang_ir", "lib/edlang_lowering","lib/edlang_parser", "lib/edlang_session", "lib/edlang_span"] [profile.release] lto = true diff --git a/lib/edlang_ast/src/lib.rs b/lib/edlang_ast/src/lib.rs index 56dd3c4b3..b5fabd001 100644 --- a/lib/edlang_ast/src/lib.rs +++ b/lib/edlang_ast/src/lib.rs @@ -39,6 +39,7 @@ pub struct PathExpr { pub enum PathSegment { Field(Ident), Index { value: Expression, span: Span }, + Method { value: FnCallExpr, span: Span }, } #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] diff --git a/lib/edlang_ir/src/lib.rs b/lib/edlang_ir/src/lib.rs index b9e45392c..45e762ef0 100644 --- a/lib/edlang_ir/src/lib.rs +++ b/lib/edlang_ir/src/lib.rs @@ -111,6 +111,7 @@ impl Body { #[derive(Debug, Clone)] pub struct AdtBody { pub def_id: DefId, + pub mod_id: DefId, pub is_pub: bool, pub name: String, pub variants: Vec, diff --git a/lib/edlang_lowering/src/lib.rs b/lib/edlang_lowering/src/lib.rs index 1dd903aff..c29daf99e 100644 --- a/lib/edlang_lowering/src/lib.rs +++ b/lib/edlang_lowering/src/lib.rs @@ -182,6 +182,7 @@ fn lower_struct( let body = ctx.body.modules.get(&module_id).unwrap(); *body.symbols.structs.get(&info.name.name).unwrap() }, + mod_id: module_id, is_pub: true, // todo struct pub name: info.name.name.clone(), variants: Vec::new(), @@ -591,6 +592,7 @@ fn find_expr_type(builder: &mut BodyBuilder, info: &ast::Expression) -> Option todo!(), + ast::PathSegment::Method { .. } => todo!(), } } @@ -1000,6 +1002,8 @@ fn lower_fn_call( let mut args = Vec::new(); + assert_eq!(args_ty.len(), info.params.len(), "param length mismatch"); + for (arg, arg_ty) in info.params.iter().zip(args_ty) { let (rvalue, _rvalue_ty, _span) = lower_expr(builder, arg, Some(&arg_ty))?; args.push(rvalue); @@ -1256,36 +1260,138 @@ fn lower_path( )?; let mut ty = builder.body.locals[local].ty.kind.clone(); - let mut projection = Vec::new(); + let mut place = Place { + local, + projection: Default::default(), + }; for extra in &info.extra { match extra { ast::PathSegment::Field(name) => { // is while fine? auto deref while let TypeKind::Ref(_, inner) = ty { - projection.push(PlaceElem::Deref); + place.projection.push(PlaceElem::Deref); ty = inner.kind; } if let TypeKind::Struct(id, _name) = 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 }); + place.projection.push(PlaceElem::Field { field_idx: idx }); ty = struct_body.variants[idx].ty.kind.clone(); + } else { + unimplemented!() } } ast::PathSegment::Index { .. } => todo!(), + ast::PathSegment::Method { value, span } => { + // is while fine? auto deref + while let TypeKind::Ref(_, inner) = ty { + place.projection.push(PlaceElem::Deref); + ty = inner.kind; + } + + if let TypeKind::Struct(id, _name) = &ty { + let struct_body = builder.ctx.body.structs.get(id).unwrap(); + let fn_id = *builder + .ctx + .body + .modules + .get(&struct_body.mod_id) + .unwrap() + .symbols + .methods + .get(id) + .unwrap() + .get(&value.name.name) + .expect("couldn't find method"); + + let (args_ty, ret_ty) = { + if let Some(x) = builder.ctx.body.function_signatures.get(&fn_id).cloned() { + x + } else { + let (args, ret) = builder + .ctx + .unresolved_function_signatures + .get(&fn_id) + .unwrap(); + + let args: Vec<_> = args + .iter() + .map(|x| lower_type(&builder.ctx, x, builder.local_module)) + .collect::, LoweringError>>()?; + let ret = ret + .as_ref() + .map(|x| lower_type(&builder.ctx, x, builder.local_module)) + .unwrap_or(Ok(TypeInfo { + span: None, + kind: TypeKind::Unit, + }))?; + builder + .ctx + .body + .function_signatures + .insert(fn_id, (args.clone(), ret.clone())); + (args, ret) + } + }; + + let mut args = Vec::new(); + + assert_eq!( + args_ty.len() - 1, + value.params.len(), + "param length mismatch" + ); + + for (arg, arg_ty) in value.params.iter().zip(&args_ty[1..]) { + let (rvalue, _rvalue_ty, _span) = lower_expr(builder, arg, Some(arg_ty))?; + args.push(rvalue); + } + + // insert self + + match &args_ty[0].kind { + TypeKind::Ptr(is_mut, _) | TypeKind::Ref(is_mut, _) => { + args.insert(0, RValue::Ref(*is_mut, Operand::Move(place), *span)); + } + _ => { + args.insert(0, RValue::Use(Operand::Move(place), *span)); + } + } + + let dest_local = builder.add_local(Local::temp(ret_ty.kind.clone())); + + place = Place { + local: dest_local, + projection: Default::default(), + }; + + let target_block = builder.body.blocks.len() + 1; + + // todo: check if function is diverging such as exit(). + let kind = Terminator::Call { + func: fn_id, + args, + destination: place.clone(), + target: Some(target_block), + }; + + let statements = std::mem::take(&mut builder.statements); + builder.body.blocks.push(BasicBlock { + statements: statements.into(), + terminator: kind, + terminator_span: Some(*span), + }); + ty = ret_ty.kind; + } else { + unimplemented!() + } + } } } - Ok(( - Place { - local, - projection: projection.into(), // todo, array - }, - ty, - info.span, - )) + Ok((place, ty, info.span)) } #[allow(clippy::only_used_in_recursion)] diff --git a/lib/edlang_parser/src/grammar.lalrpop b/lib/edlang_parser/src/grammar.lalrpop index 29ee8e344..976069c5f 100644 --- a/lib/edlang_parser/src/grammar.lalrpop +++ b/lib/edlang_parser/src/grammar.lalrpop @@ -199,6 +199,10 @@ pub PathSegments: Vec = { pub(crate) PathSegment: ast::PathSegment = { "." => ast::PathSegment::Field(<>), + "." => ast::PathSegment::Method { + value, + span: ast::Span::new(lo, hi), + }, "[" "]" => ast::PathSegment::Index { value, span: ast::Span::new(lo, hi), diff --git a/program b/program new file mode 100755 index 0000000000000000000000000000000000000000..bac4636d753e71464b8d031c205e5612d7e78fee GIT binary patch literal 15808 zcmeHOTWlOx89uW&uf5KCZKuK|X*+@~3J;$6RyS=SSvz*T1~&<*OM^h2tg~Z#>3Vmy zJFeEHQlT*jlU8a~smc>iydWWwhl;mCP%0sikcbc>4?I+;NO=gV5f>pEb@~1||G%9~ zoKhhK5<0&$^PT^8F5jM+J-c(}h54luG0RdSadlLYX6Lk}z>dN+7XSryMD4@*es!Np zK~DrW?JsD6SIhO-?U-hJ97uU1RM-O#YO@lQ9uiXC-K4=zLB->syd)*D9>q7gLP7C& z+p{?!g4=8s4CfIyZAS;RkKT?i@qh#+kLdcaymOoklG-5;tziL-)ZkO=Oyf*8WqL7HY-7C?+eHyUOuYG$9#s{yW8jRZRS&uRdu*p zS(%rDMLG>+S}iOs&K`FsoXIJKt!>n6 z9OhC*G47wGhM@_cZ@l_CK86^sd@a|HX{67F`X=&r$Sz|RpFzWbVZbn87%&VN1`Gp+ z0mFb{;D5uwp9k*$NAbeVbn#;H+F_-N-@M|-I=?Djcq@H1=n(nG|G2nw?djsq?~51S z**(2HKYnHW=f#&lJC1<@%g^U?Kc-(yH{R@YIxr>RN&x$T{lNXe{pi%l)oy>g zJq(&PC&PeYz%XDKFbo(53GHFkl!k3>XGJgaM15^BsskW+R54PafRubUp)I z0xkoqz;)n$93<9rXOz{>SqJ)i(y!owAKB>{{q=V{oljA~Tu<<*kWN!Lc43!ig%n%F zaSOHrP|aoSuVv*)G#QK-1`Gp+0mFb{z%XDKFbo(538Rw8k-m&vm4`6pJuBqMm36h^tRsLqC|V#8_oJ!v$UZmQC|0|)w9J>9FEKEj~NxFOO90)m%_b;-^~cU!cG=1!6+X*g>9Du@Uj07gM*XJ$GiKFT*OH&19%DrF!#Fj%G3__T|(fT~HMq3H1r; zpJlz5-A6#I z$hVTYRN6`QrM8pt)Qg$V#geGmD_2XkwQ#lCGTJIXBUU{l@?-gjcy4S?PUyMORxPi( zs%9`-=x?MC<`mI8qlkNo{g*<+OQ=6}_6pp~PWKxNyV|4Ig}yIjyYD4PeTRbhA$5cI zwTqo5On4TH{i`V0v~#{77L8v9?^Pj#roA{o{%~kmlDTE>)C|emY@)BqdbVW zbHpjPo7Z5ccGHDWFp4!CLn_mK-zWGF54KA<_Uh;NI6iz;!KA)V_E=x{{!O+(_`X2X z&7J$w$(hF&kK<(nyb|Hg7u^$QW*(n+i*sj`yRdX>c4o;vb>hSm^ULn?%b1*-%cc?t9K!ZPUTf8eY@iV$;m*;;3I*Q-N>2)LK_gd8>x{H2O{L zdDd&TD)riJiVI)UtClE1IYCbx-)sBI2?pmh>%mYRZ{1zRP1bYQ%g7KdsK2yPIgdK) z$ic~JR8i1L=j$6AxVJ;~RyNn%#^y>5RkTE})K=?KF0HIIy=O(kn=hV}L4p)ffxp#2 z1^)>-fJ*4v)ffJq?}O1zAuJRdmQO;VZxYEr!r%Xbb~qSi`Cb<@z19}aKg;=owgfWD z^(5vw6#jj$`=oZgY>$VY#iRTC)hCAwdjK63;qsfDThNJ=6u>@8