This commit is contained in:
Edgar 2024-02-04 17:27:06 +01:00
parent 7a784dd73b
commit 572f1aee09
No known key found for this signature in database
GPG key ID: 70ADAE8F35904387
4 changed files with 126 additions and 12 deletions

View file

@ -4,6 +4,7 @@ use edlang_ir as ir;
use edlang_ir::DefId;
use edlang_session::Session;
use inkwell::{
attributes::Attribute,
builder::{Builder, BuilderError},
context::Context,
debug_info::{DICompileUnit, DebugInfoBuilder},
@ -12,7 +13,7 @@ use inkwell::{
types::{AnyType, BasicMetadataTypeEnum, BasicType},
values::{AnyValue, AnyValueEnum, BasicValue, BasicValueEnum, PointerValue},
};
use ir::{TypeInfo, ValueTree};
use ir::{ConstData, Operand, TypeInfo, ValueTree};
use tracing::info;
#[derive(Debug, Clone, Copy)]
@ -153,7 +154,7 @@ fn compile_fn_signature(ctx: &ModuleCompileCtx, body: &ir::Body) {
compile_basic_type(ctx, &ret_type).fn_type(&args, false)
};
ctx.module.add_function(
let fn_value = ctx.module.add_function(
name,
fn_type,
Some(if body.is_extern {
@ -164,6 +165,12 @@ fn compile_fn_signature(ctx: &ModuleCompileCtx, body: &ir::Body) {
inkwell::module::Linkage::Private
}),
);
// nonlazybind
fn_value.add_attribute(
inkwell::attributes::AttributeLoc::Function,
ctx.ctx.context.create_enum_attribute(37, 0),
);
}
fn compile_fn(ctx: &ModuleCompileCtx, body: &ir::Body) -> Result<(), BuilderError> {
@ -273,8 +280,47 @@ fn compile_fn(ctx: &ModuleCompileCtx, body: &ir::Body) -> Result<(), BuilderErro
args,
dest,
target,
} => todo!(),
ir::Terminator::Unreachable => todo!(),
} => {
if let Operand::Constant(c) = func {
if let ir::TypeKind::FnDef(fn_id, generics) = &c.type_info.kind {
let fn_symbol = ctx.ctx.symbols.get(fn_id).unwrap();
let fn_value = ctx.module.get_function(fn_symbol).unwrap();
let args: Vec<_> = args
.iter()
.map(|x| {
compile_load_operand(ctx, body, &locals, x)
.unwrap()
.0
.into()
})
.collect();
let result = ctx.builder.build_call(fn_value, &args, "")?;
if let Some(dest) = dest {
let is_void =
matches!(body.locals[dest.local].ty.kind, ir::TypeKind::Unit);
if !is_void {
ctx.builder.build_store(
*locals.get(&dest.local).unwrap(),
result.try_as_basic_value().expect_left("value was right"),
)?;
}
}
if let Some(target) = target {
ctx.builder.build_unconditional_branch(blocks[*target])?;
}
} else {
todo!()
}
} else {
todo!()
}
}
ir::Terminator::Unreachable => {
ctx.builder.build_unreachable()?;
}
}
}
@ -645,10 +691,7 @@ fn compile_value<'ctx>(
.into_int_type()
.const_int((*x) as u64, true)
.as_basic_value_enum(),
ir::ConstValue::U64(x) => ty
.into_int_type()
.const_int((*x) as u64, true)
.as_basic_value_enum(),
ir::ConstValue::U64(x) => ty.into_int_type().const_int(*x, true).as_basic_value_enum(),
ir::ConstValue::U128(x) => ty
.into_int_type()
.const_int((*x) as u64, true)
@ -702,7 +745,7 @@ fn compile_basic_type<'ctx>(
) -> inkwell::types::BasicTypeEnum<'ctx> {
// ctx.di_builder.create_basic_type(name, size_in_bits, encoding, flags)
match &ty.kind {
ir::TypeKind::Unit => panic!(),
ir::TypeKind::Unit => todo!(),
ir::TypeKind::Bool => ctx.ctx.context.bool_type().as_basic_type_enum(),
ir::TypeKind::Char => ctx.ctx.context.i32_type().as_basic_type_enum(),
ir::TypeKind::Int(ty) => match ty {

View file

@ -109,7 +109,7 @@ pub enum Terminator {
Call {
func: Operand,
args: Vec<Operand>,
dest: Place,
dest: Option<Place>,
target: Option<usize>, // block
},
Unreachable,
@ -133,6 +133,10 @@ pub enum TypeKind {
}
impl TypeKind {
pub fn is_unit(&self) -> bool {
matches!(self, Self::Unit)
}
pub fn get_falsy_value(&self) -> ValueTree {
match self {
Self::Bool => ValueTree::Leaf(ConstValue::Bool(false)),

View file

@ -184,7 +184,9 @@ fn lower_function(
ast::Statement::While(_) => todo!(),
ast::Statement::If(_) => todo!(),
ast::Statement::Return(info) => lower_return(&mut builder, info),
ast::Statement::FnCall(_) => todo!(),
ast::Statement::FnCall(info) => {
lower_fn_call_no_ret(&mut builder, info);
}
}
}
@ -370,6 +372,70 @@ fn lower_binary_expr(
}
}
fn lower_fn_call_no_ret(builder: &mut BodyBuilder, info: &ast::FnCallExpr) {
let (arg_types, _ret_type) = builder.get_fn_by_name(&info.name.name).unwrap().clone();
let mut args = Vec::new();
for (expr, ty) in info.params.iter().zip(arg_types) {
let rvalue = lower_expr(builder, expr, Some(&ty));
let local = builder.add_local(Local {
mutable: false,
span: None,
ty,
kind: ir::LocalKind::Temp,
});
let place = Place {
local,
projection: Default::default(),
};
builder.statements.push(Statement {
span: None,
kind: ir::StatementKind::StorageLive(local),
});
builder.statements.push(Statement {
span: None,
kind: ir::StatementKind::Assign(place.clone(), rvalue),
});
args.push(Operand::Move(place))
}
let fn_id = *builder
.get_current_module()
.func_name_to_id
.get(&info.name.name)
.unwrap();
let next_block = builder.body.blocks.len() + 1;
let terminator = Terminator::Call {
func: Operand::Constant(ConstData {
span: Some(info.span),
type_info: TypeInfo {
span: None,
kind: ir::TypeKind::FnDef(fn_id, vec![]),
},
kind: ConstKind::ZeroSized,
}),
args,
dest: None,
target: Some(next_block),
};
let statements = std::mem::take(&mut builder.statements);
builder.body.blocks.push(ir::BasicBlock {
id: builder.body.blocks.len(),
statements: statements.into(),
terminator,
});
}
fn lower_fn_call(builder: &mut BodyBuilder, info: &ast::FnCallExpr) -> ir::Operand {
let (arg_types, ret_type) = builder.get_fn_by_name(&info.name.name).unwrap().clone();
@ -438,7 +504,7 @@ fn lower_fn_call(builder: &mut BodyBuilder, info: &ast::FnCallExpr) -> ir::Opera
kind: ConstKind::ZeroSized,
}),
args,
dest: dest_place.clone(),
dest: Some(dest_place.clone()),
target: Some(next_block),
};

View file

@ -3,6 +3,7 @@ mod Main {
pub fn main(argc: i32) -> i32 {
let mut x: i32 = 2;
x = 4;
a();
return x + 2;
}