diff --git a/Cargo.lock b/Cargo.lock index cb94f3f7f..f9c3ae189 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -355,6 +355,7 @@ name = "edlang_ir" version = "0.0.1-alpha.10" dependencies = [ "edlang_span", + "educe", "smallvec", ] @@ -392,6 +393,18 @@ dependencies = [ name = "edlang_span" version = "0.0.1-alpha.10" +[[package]] +name = "educe" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4bd92664bf78c4d3dba9b7cdafce6fa15b13ed3ed16175218196942e99168a8" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "either" version = "1.10.0" @@ -407,6 +420,26 @@ dependencies = [ "log", ] +[[package]] +name = "enum-ordinalize" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "equivalent" version = "1.0.1" diff --git a/lib/edlang_ast/src/lib.rs b/lib/edlang_ast/src/lib.rs index afc890a6b..a293ae8d5 100644 --- a/lib/edlang_ast/src/lib.rs +++ b/lib/edlang_ast/src/lib.rs @@ -140,7 +140,7 @@ pub struct Function { pub is_public: bool, pub params: Vec, pub return_type: Option, - pub body: Block, + pub body: Option, pub span: Span, } diff --git a/lib/edlang_codegen_llvm/src/codegen.rs b/lib/edlang_codegen_llvm/src/codegen.rs index 89fc754be..d41f52491 100644 --- a/lib/edlang_codegen_llvm/src/codegen.rs +++ b/lib/edlang_codegen_llvm/src/codegen.rs @@ -223,9 +223,7 @@ fn compile_fn_signature(ctx: &ModuleCompileCtx<'_, '_>, fn_id: DefId) { let fn_value = ctx.module.add_function( &body.get_mangled_name(), fn_type, - Some(if body.is_extern { - inkwell::module::Linkage::AvailableExternally - } else if body.is_pub { + Some(if body.is_pub || body.is_extern { inkwell::module::Linkage::External } else { inkwell::module::Linkage::Private @@ -261,7 +259,7 @@ fn compile_fn_signature(ctx: &ModuleCompileCtx<'_, '_>, fn_id: DefId) { line as u32 + 1, di_type, body.is_pub, - true, + !body.is_extern, line as u32 + 1, 0, false, @@ -271,6 +269,11 @@ fn compile_fn_signature(ctx: &ModuleCompileCtx<'_, '_>, fn_id: DefId) { fn compile_fn(ctx: &ModuleCompileCtx, fn_id: DefId) -> Result<(), BuilderError> { let body = ctx.ctx.program.functions.get(&fn_id).unwrap(); + + if body.is_extern { + return Ok(()); + } + trace!("compiling fn body: {}", body.name); let fn_value = ctx.module.get_function(&body.get_mangled_name()).unwrap(); diff --git a/lib/edlang_ir/Cargo.toml b/lib/edlang_ir/Cargo.toml index 11a812bb5..d12636e2f 100644 --- a/lib/edlang_ir/Cargo.toml +++ b/lib/edlang_ir/Cargo.toml @@ -15,3 +15,4 @@ repository = "https://github.com/edg-l/edlang" [dependencies] edlang_span = { version = "0.0.1-alpha.10", path = "../edlang_span" } smallvec = "1.13.1" +educe = "0.5.11" diff --git a/lib/edlang_ir/src/lib.rs b/lib/edlang_ir/src/lib.rs index a0633bb16..59476ab37 100644 --- a/lib/edlang_ir/src/lib.rs +++ b/lib/edlang_ir/src/lib.rs @@ -6,6 +6,7 @@ use std::{ }; use edlang_span::Span; +use educe::Educe; use smallvec::SmallVec; pub mod scalar_int; @@ -91,6 +92,10 @@ impl Body { } pub fn get_mangled_name(&self) -> String { + if self.is_extern { + return self.name.clone(); + } + if self.name == "main" { "main".to_string() } else { @@ -221,8 +226,10 @@ pub struct SwitchTarget { pub targets: Vec, } -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, Clone, Educe, Eq, PartialOrd, Ord)] +#[educe(PartialEq)] pub struct TypeInfo { + #[educe(PartialEq(ignore))] pub span: Option, pub kind: TypeKind, } diff --git a/lib/edlang_lowering/src/lib.rs b/lib/edlang_lowering/src/lib.rs index a9ac87d26..aff8150f0 100644 --- a/lib/edlang_lowering/src/lib.rs +++ b/lib/edlang_lowering/src/lib.rs @@ -170,60 +170,61 @@ fn lower_function( .unwrap() .clone(); - // store args ret + if func.body.is_some() && !func.is_extern { + // store args ret - builder.ret_local = builder.body.locals.len(); - builder.body.locals.push(Local::new( - None, - LocalKind::ReturnPointer, - ret_ty.clone(), - None, - false, - )); - - for (arg, ty) in func.params.iter().zip(args_ty) { - builder - .name_to_local - .insert(arg.name.name.clone(), builder.body.locals.len()); + builder.ret_local = builder.body.locals.len(); builder.body.locals.push(Local::new( - Some(arg.name.span), - LocalKind::Arg, - ty, - Some(arg.name.name.clone()), + None, + LocalKind::ReturnPointer, + ret_ty.clone(), + None, false, )); - } - // Get all user defined locals - for stmt in &func.body.body { - if let ast::Statement::Let(info) = stmt { - let ty = lower_type(&builder.ctx, &info.r#type, builder.local_module)?; + for (arg, ty) in func.params.iter().zip(args_ty) { builder .name_to_local - .insert(info.name.name.clone(), builder.body.locals.len()); + .insert(arg.name.name.clone(), builder.body.locals.len()); builder.body.locals.push(Local::new( - Some(info.name.span), - LocalKind::Temp, + Some(arg.name.span), + LocalKind::Arg, ty, - Some(info.name.name.clone()), - info.is_mut, + Some(arg.name.name.clone()), + false, )); } - } - for stmt in &func.body.body { - lower_statement(&mut builder, stmt, &ret_ty)?; - } + // Get all user defined locals + for stmt in &func.body.as_ref().unwrap().body { + if let ast::Statement::Let(info) = stmt { + let ty = lower_type(&builder.ctx, &info.r#type, builder.local_module)?; + builder + .name_to_local + .insert(info.name.name.clone(), builder.body.locals.len()); + builder.body.locals.push(Local::new( + Some(info.name.span), + LocalKind::Temp, + ty, + Some(info.name.name.clone()), + info.is_mut, + )); + } + } - if !builder.statements.is_empty() { - let statements = std::mem::take(&mut builder.statements); - builder.body.blocks.push(BasicBlock { - statements: statements.into(), - terminator: Terminator::Return, - terminator_span: None, - }); - } + for stmt in &func.body.as_ref().unwrap().body { + lower_statement(&mut builder, stmt, &ret_ty)?; + } + if !builder.statements.is_empty() { + let statements = std::mem::take(&mut builder.statements); + builder.body.blocks.push(BasicBlock { + statements: statements.into(), + terminator: Terminator::Return, + terminator_span: None, + }); + } + } let (mut ctx, body) = (builder.ctx, builder.body); ctx.unresolved_function_signatures.remove(&body.def_id); ctx.body.functions.insert(body.def_id, body); @@ -478,6 +479,8 @@ fn lower_assign(builder: &mut BodyBuilder, info: &ast::AssignStmt) -> Result<(), kind: ty, }; + dbg!("here1"); + for _ in 0..info.deref_times { match &ty.kind { TypeKind::Ptr(is_mut, inner) => { @@ -497,8 +500,12 @@ fn lower_assign(builder: &mut BodyBuilder, info: &ast::AssignStmt) -> Result<(), place.projection.push(PlaceElem::Deref); } + dbg!("here2"); + let (rvalue, _ty, _span) = lower_expr(builder, &info.value, Some(&ty))?; + dbg!("here3"); + builder.statements.push(Statement { span: Some(info.name.first.span), kind: StatementKind::Assign(place, rvalue), @@ -1062,8 +1069,6 @@ fn lower_return( let (value, ty, span) = lower_expr(builder, value_expr, Some(return_type))?; if return_type.kind != ty { - dbg!("here"); - dbg!(value); return Err(LoweringError::UnexpectedType { span, found: ty, diff --git a/lib/edlang_parser/src/grammar.lalrpop b/lib/edlang_parser/src/grammar.lalrpop index adf58540d..af8f15ca1 100644 --- a/lib/edlang_parser/src/grammar.lalrpop +++ b/lib/edlang_parser/src/grammar.lalrpop @@ -420,14 +420,24 @@ pub(crate) FnParam: ast::FnParam = { } pub(crate) Function: ast::Function = { - "fn" "(" > ")" - " )?> => ast::Function { + "extern" "fn" "(" > ")" + " )?> ";" => ast::Function { is_public: is_public.is_some(), - is_extern: is_extern.is_some(), + is_extern: true, name, params, return_type, - body, + body: None, + span: ast::Span::new(lo, hi), + }, + "fn" "(" > ")" + " )?> => ast::Function { + is_public: is_public.is_some(), + is_extern: false, + name, + params, + return_type, + body: Some(body), span: ast::Span::new(lo, hi), } }