feat: allow extern fns

This commit is contained in:
Edgar 2024-02-28 09:53:58 +01:00
parent dd7b949a44
commit 3872c0128b
No known key found for this signature in database
GPG key ID: 70ADAE8F35904387
7 changed files with 111 additions and 52 deletions

33
Cargo.lock generated
View file

@ -355,6 +355,7 @@ name = "edlang_ir"
version = "0.0.1-alpha.10" version = "0.0.1-alpha.10"
dependencies = [ dependencies = [
"edlang_span", "edlang_span",
"educe",
"smallvec", "smallvec",
] ]
@ -392,6 +393,18 @@ dependencies = [
name = "edlang_span" name = "edlang_span"
version = "0.0.1-alpha.10" 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]] [[package]]
name = "either" name = "either"
version = "1.10.0" version = "1.10.0"
@ -407,6 +420,26 @@ dependencies = [
"log", "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]] [[package]]
name = "equivalent" name = "equivalent"
version = "1.0.1" version = "1.0.1"

View file

@ -140,7 +140,7 @@ pub struct Function {
pub is_public: bool, pub is_public: bool,
pub params: Vec<FnParam>, pub params: Vec<FnParam>,
pub return_type: Option<Type>, pub return_type: Option<Type>,
pub body: Block, pub body: Option<Block>,
pub span: Span, pub span: Span,
} }

View file

@ -223,9 +223,7 @@ fn compile_fn_signature(ctx: &ModuleCompileCtx<'_, '_>, fn_id: DefId) {
let fn_value = ctx.module.add_function( let fn_value = ctx.module.add_function(
&body.get_mangled_name(), &body.get_mangled_name(),
fn_type, fn_type,
Some(if body.is_extern { Some(if body.is_pub || body.is_extern {
inkwell::module::Linkage::AvailableExternally
} else if body.is_pub {
inkwell::module::Linkage::External inkwell::module::Linkage::External
} else { } else {
inkwell::module::Linkage::Private inkwell::module::Linkage::Private
@ -261,7 +259,7 @@ fn compile_fn_signature(ctx: &ModuleCompileCtx<'_, '_>, fn_id: DefId) {
line as u32 + 1, line as u32 + 1,
di_type, di_type,
body.is_pub, body.is_pub,
true, !body.is_extern,
line as u32 + 1, line as u32 + 1,
0, 0,
false, false,
@ -271,6 +269,11 @@ fn compile_fn_signature(ctx: &ModuleCompileCtx<'_, '_>, fn_id: DefId) {
fn compile_fn(ctx: &ModuleCompileCtx, fn_id: DefId) -> Result<(), BuilderError> { fn compile_fn(ctx: &ModuleCompileCtx, fn_id: DefId) -> Result<(), BuilderError> {
let body = ctx.ctx.program.functions.get(&fn_id).unwrap(); let body = ctx.ctx.program.functions.get(&fn_id).unwrap();
if body.is_extern {
return Ok(());
}
trace!("compiling fn body: {}", body.name); trace!("compiling fn body: {}", body.name);
let fn_value = ctx.module.get_function(&body.get_mangled_name()).unwrap(); let fn_value = ctx.module.get_function(&body.get_mangled_name()).unwrap();

View file

@ -15,3 +15,4 @@ repository = "https://github.com/edg-l/edlang"
[dependencies] [dependencies]
edlang_span = { version = "0.0.1-alpha.10", path = "../edlang_span" } edlang_span = { version = "0.0.1-alpha.10", path = "../edlang_span" }
smallvec = "1.13.1" smallvec = "1.13.1"
educe = "0.5.11"

View file

@ -6,6 +6,7 @@ use std::{
}; };
use edlang_span::Span; use edlang_span::Span;
use educe::Educe;
use smallvec::SmallVec; use smallvec::SmallVec;
pub mod scalar_int; pub mod scalar_int;
@ -91,6 +92,10 @@ impl Body {
} }
pub fn get_mangled_name(&self) -> String { pub fn get_mangled_name(&self) -> String {
if self.is_extern {
return self.name.clone();
}
if self.name == "main" { if self.name == "main" {
"main".to_string() "main".to_string()
} else { } else {
@ -221,8 +226,10 @@ pub struct SwitchTarget {
pub targets: Vec<usize>, pub targets: Vec<usize>,
} }
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Clone, Educe, Eq, PartialOrd, Ord)]
#[educe(PartialEq)]
pub struct TypeInfo { pub struct TypeInfo {
#[educe(PartialEq(ignore))]
pub span: Option<Span>, pub span: Option<Span>,
pub kind: TypeKind, pub kind: TypeKind,
} }

View file

@ -170,6 +170,7 @@ fn lower_function(
.unwrap() .unwrap()
.clone(); .clone();
if func.body.is_some() && !func.is_extern {
// store args ret // store args ret
builder.ret_local = builder.body.locals.len(); builder.ret_local = builder.body.locals.len();
@ -195,7 +196,7 @@ fn lower_function(
} }
// Get all user defined locals // Get all user defined locals
for stmt in &func.body.body { for stmt in &func.body.as_ref().unwrap().body {
if let ast::Statement::Let(info) = stmt { if let ast::Statement::Let(info) = stmt {
let ty = lower_type(&builder.ctx, &info.r#type, builder.local_module)?; let ty = lower_type(&builder.ctx, &info.r#type, builder.local_module)?;
builder builder
@ -211,7 +212,7 @@ fn lower_function(
} }
} }
for stmt in &func.body.body { for stmt in &func.body.as_ref().unwrap().body {
lower_statement(&mut builder, stmt, &ret_ty)?; lower_statement(&mut builder, stmt, &ret_ty)?;
} }
@ -223,7 +224,7 @@ fn lower_function(
terminator_span: None, terminator_span: None,
}); });
} }
}
let (mut ctx, body) = (builder.ctx, builder.body); let (mut ctx, body) = (builder.ctx, builder.body);
ctx.unresolved_function_signatures.remove(&body.def_id); ctx.unresolved_function_signatures.remove(&body.def_id);
ctx.body.functions.insert(body.def_id, body); ctx.body.functions.insert(body.def_id, body);
@ -478,6 +479,8 @@ fn lower_assign(builder: &mut BodyBuilder, info: &ast::AssignStmt) -> Result<(),
kind: ty, kind: ty,
}; };
dbg!("here1");
for _ in 0..info.deref_times { for _ in 0..info.deref_times {
match &ty.kind { match &ty.kind {
TypeKind::Ptr(is_mut, inner) => { TypeKind::Ptr(is_mut, inner) => {
@ -497,8 +500,12 @@ fn lower_assign(builder: &mut BodyBuilder, info: &ast::AssignStmt) -> Result<(),
place.projection.push(PlaceElem::Deref); place.projection.push(PlaceElem::Deref);
} }
dbg!("here2");
let (rvalue, _ty, _span) = lower_expr(builder, &info.value, Some(&ty))?; let (rvalue, _ty, _span) = lower_expr(builder, &info.value, Some(&ty))?;
dbg!("here3");
builder.statements.push(Statement { builder.statements.push(Statement {
span: Some(info.name.first.span), span: Some(info.name.first.span),
kind: StatementKind::Assign(place, rvalue), kind: StatementKind::Assign(place, rvalue),
@ -1062,8 +1069,6 @@ fn lower_return(
let (value, ty, span) = lower_expr(builder, value_expr, Some(return_type))?; let (value, ty, span) = lower_expr(builder, value_expr, Some(return_type))?;
if return_type.kind != ty { if return_type.kind != ty {
dbg!("here");
dbg!(value);
return Err(LoweringError::UnexpectedType { return Err(LoweringError::UnexpectedType {
span, span,
found: ty, found: ty,

View file

@ -420,14 +420,24 @@ pub(crate) FnParam: ast::FnParam = {
} }
pub(crate) Function: ast::Function = { pub(crate) Function: ast::Function = {
<lo:@L> <is_public:"pub"?> <is_extern:"extern"?> "fn" <name:Ident> "(" <params:Comma<FnParam>> ")" <lo:@L> <is_public:"pub"?> "extern" "fn" <name:Ident> "(" <params:Comma<FnParam>> ")"
<return_type:("->" <Type>)?> <body:Block> <hi:@R> => ast::Function { <return_type:("->" <Type>)?> ";" <hi:@R> => ast::Function {
is_public: is_public.is_some(), is_public: is_public.is_some(),
is_extern: is_extern.is_some(), is_extern: true,
name, name,
params, params,
return_type, return_type,
body, body: None,
span: ast::Span::new(lo, hi),
},
<lo:@L> <is_public:"pub"?> "fn" <name:Ident> "(" <params:Comma<FnParam>> ")"
<return_type:("->" <Type>)?> <body:Block> <hi:@R> => ast::Function {
is_public: is_public.is_some(),
is_extern: false,
name,
params,
return_type,
body: Some(body),
span: ast::Span::new(lo, hi), span: ast::Span::new(lo, hi),
} }
} }