Skip to content

Commit

Permalink
feat: allow extern fns
Browse files Browse the repository at this point in the history
  • Loading branch information
edg-l committed Feb 28, 2024
1 parent dd7b949 commit 3872c01
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 52 deletions.
33 changes: 33 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/edlang_ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ pub struct Function {
pub is_public: bool,
pub params: Vec<FnParam>,
pub return_type: Option<Type>,
pub body: Block,
pub body: Option<Block>,
pub span: Span,
}

Expand Down
11 changes: 7 additions & 4 deletions lib/edlang_codegen_llvm/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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();
Expand Down
1 change: 1 addition & 0 deletions lib/edlang_ir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
9 changes: 8 additions & 1 deletion lib/edlang_ir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::{
};

use edlang_span::Span;
use educe::Educe;
use smallvec::SmallVec;

pub mod scalar_int;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -221,8 +226,10 @@ pub struct SwitchTarget {
pub targets: Vec<usize>,
}

#[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<Span>,
pub kind: TypeKind,
}
Expand Down
91 changes: 48 additions & 43 deletions lib/edlang_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,60 +170,61 @@ fn lower_function(
.unwrap()
.clone();

// 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());
if func.body.is_some() && !func.is_extern {
// store args ret

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);
Expand Down Expand Up @@ -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) => {
Expand All @@ -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),
Expand Down Expand Up @@ -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,
Expand Down
16 changes: 13 additions & 3 deletions lib/edlang_parser/src/grammar.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -420,14 +420,24 @@ pub(crate) FnParam: ast::FnParam = {
}

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>)?> ";" <hi:@R> => ast::Function {
is_public: is_public.is_some(),
is_extern: true,
name,
params,
return_type,
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: is_extern.is_some(),
is_extern: false,
name,
params,
return_type,
body,
body: Some(body),
span: ast::Span::new(lo, hi),
}
}
Expand Down

0 comments on commit 3872c01

Please sign in to comment.