mirror of
https://github.com/edg-l/edlang.git
synced 2024-11-22 07:58:24 +00:00
feat: allow extern fns
This commit is contained in:
parent
dd7b949a44
commit
3872c0128b
33
Cargo.lock
generated
33
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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<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,
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>> ")"
|
||||
<return_type:("->" <Type>)?> <body:Block> <hi:@R> => ast::Function {
|
||||
<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: is_extern.is_some(),
|
||||
is_extern: true,
|
||||
name,
|
||||
params,
|
||||
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),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue