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"
|
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"
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,60 +170,61 @@ fn lower_function(
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
// store args ret
|
if func.body.is_some() && !func.is_extern {
|
||||||
|
// store args ret
|
||||||
|
|
||||||
builder.ret_local = builder.body.locals.len();
|
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.body.locals.push(Local::new(
|
builder.body.locals.push(Local::new(
|
||||||
Some(arg.name.span),
|
None,
|
||||||
LocalKind::Arg,
|
LocalKind::ReturnPointer,
|
||||||
ty,
|
ret_ty.clone(),
|
||||||
Some(arg.name.name.clone()),
|
None,
|
||||||
false,
|
false,
|
||||||
));
|
));
|
||||||
}
|
|
||||||
|
|
||||||
// Get all user defined locals
|
for (arg, ty) in func.params.iter().zip(args_ty) {
|
||||||
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)?;
|
|
||||||
builder
|
builder
|
||||||
.name_to_local
|
.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(
|
builder.body.locals.push(Local::new(
|
||||||
Some(info.name.span),
|
Some(arg.name.span),
|
||||||
LocalKind::Temp,
|
LocalKind::Arg,
|
||||||
ty,
|
ty,
|
||||||
Some(info.name.name.clone()),
|
Some(arg.name.name.clone()),
|
||||||
info.is_mut,
|
false,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for stmt in &func.body.body {
|
// Get all user defined locals
|
||||||
lower_statement(&mut builder, stmt, &ret_ty)?;
|
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() {
|
for stmt in &func.body.as_ref().unwrap().body {
|
||||||
let statements = std::mem::take(&mut builder.statements);
|
lower_statement(&mut builder, stmt, &ret_ty)?;
|
||||||
builder.body.blocks.push(BasicBlock {
|
}
|
||||||
statements: statements.into(),
|
|
||||||
terminator: Terminator::Return,
|
|
||||||
terminator_span: None,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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);
|
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,
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue