mirror of
https://github.com/edg-l/edlang.git
synced 2024-11-22 16:08:24 +00:00
prog
This commit is contained in:
parent
7a784dd73b
commit
572f1aee09
|
@ -4,6 +4,7 @@ use edlang_ir as ir;
|
||||||
use edlang_ir::DefId;
|
use edlang_ir::DefId;
|
||||||
use edlang_session::Session;
|
use edlang_session::Session;
|
||||||
use inkwell::{
|
use inkwell::{
|
||||||
|
attributes::Attribute,
|
||||||
builder::{Builder, BuilderError},
|
builder::{Builder, BuilderError},
|
||||||
context::Context,
|
context::Context,
|
||||||
debug_info::{DICompileUnit, DebugInfoBuilder},
|
debug_info::{DICompileUnit, DebugInfoBuilder},
|
||||||
|
@ -12,7 +13,7 @@ use inkwell::{
|
||||||
types::{AnyType, BasicMetadataTypeEnum, BasicType},
|
types::{AnyType, BasicMetadataTypeEnum, BasicType},
|
||||||
values::{AnyValue, AnyValueEnum, BasicValue, BasicValueEnum, PointerValue},
|
values::{AnyValue, AnyValueEnum, BasicValue, BasicValueEnum, PointerValue},
|
||||||
};
|
};
|
||||||
use ir::{TypeInfo, ValueTree};
|
use ir::{ConstData, Operand, TypeInfo, ValueTree};
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[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)
|
compile_basic_type(ctx, &ret_type).fn_type(&args, false)
|
||||||
};
|
};
|
||||||
|
|
||||||
ctx.module.add_function(
|
let fn_value = ctx.module.add_function(
|
||||||
name,
|
name,
|
||||||
fn_type,
|
fn_type,
|
||||||
Some(if body.is_extern {
|
Some(if body.is_extern {
|
||||||
|
@ -164,6 +165,12 @@ fn compile_fn_signature(ctx: &ModuleCompileCtx, body: &ir::Body) {
|
||||||
inkwell::module::Linkage::Private
|
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> {
|
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,
|
args,
|
||||||
dest,
|
dest,
|
||||||
target,
|
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()
|
.into_int_type()
|
||||||
.const_int((*x) as u64, true)
|
.const_int((*x) as u64, true)
|
||||||
.as_basic_value_enum(),
|
.as_basic_value_enum(),
|
||||||
ir::ConstValue::U64(x) => ty
|
ir::ConstValue::U64(x) => ty.into_int_type().const_int(*x, true).as_basic_value_enum(),
|
||||||
.into_int_type()
|
|
||||||
.const_int((*x) as u64, true)
|
|
||||||
.as_basic_value_enum(),
|
|
||||||
ir::ConstValue::U128(x) => ty
|
ir::ConstValue::U128(x) => ty
|
||||||
.into_int_type()
|
.into_int_type()
|
||||||
.const_int((*x) as u64, true)
|
.const_int((*x) as u64, true)
|
||||||
|
@ -702,7 +745,7 @@ fn compile_basic_type<'ctx>(
|
||||||
) -> inkwell::types::BasicTypeEnum<'ctx> {
|
) -> inkwell::types::BasicTypeEnum<'ctx> {
|
||||||
// ctx.di_builder.create_basic_type(name, size_in_bits, encoding, flags)
|
// ctx.di_builder.create_basic_type(name, size_in_bits, encoding, flags)
|
||||||
match &ty.kind {
|
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::Bool => ctx.ctx.context.bool_type().as_basic_type_enum(),
|
||||||
ir::TypeKind::Char => ctx.ctx.context.i32_type().as_basic_type_enum(),
|
ir::TypeKind::Char => ctx.ctx.context.i32_type().as_basic_type_enum(),
|
||||||
ir::TypeKind::Int(ty) => match ty {
|
ir::TypeKind::Int(ty) => match ty {
|
||||||
|
|
|
@ -109,7 +109,7 @@ pub enum Terminator {
|
||||||
Call {
|
Call {
|
||||||
func: Operand,
|
func: Operand,
|
||||||
args: Vec<Operand>,
|
args: Vec<Operand>,
|
||||||
dest: Place,
|
dest: Option<Place>,
|
||||||
target: Option<usize>, // block
|
target: Option<usize>, // block
|
||||||
},
|
},
|
||||||
Unreachable,
|
Unreachable,
|
||||||
|
@ -133,6 +133,10 @@ pub enum TypeKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeKind {
|
impl TypeKind {
|
||||||
|
pub fn is_unit(&self) -> bool {
|
||||||
|
matches!(self, Self::Unit)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_falsy_value(&self) -> ValueTree {
|
pub fn get_falsy_value(&self) -> ValueTree {
|
||||||
match self {
|
match self {
|
||||||
Self::Bool => ValueTree::Leaf(ConstValue::Bool(false)),
|
Self::Bool => ValueTree::Leaf(ConstValue::Bool(false)),
|
||||||
|
|
|
@ -184,7 +184,9 @@ fn lower_function(
|
||||||
ast::Statement::While(_) => todo!(),
|
ast::Statement::While(_) => todo!(),
|
||||||
ast::Statement::If(_) => todo!(),
|
ast::Statement::If(_) => todo!(),
|
||||||
ast::Statement::Return(info) => lower_return(&mut builder, info),
|
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 {
|
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();
|
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,
|
kind: ConstKind::ZeroSized,
|
||||||
}),
|
}),
|
||||||
args,
|
args,
|
||||||
dest: dest_place.clone(),
|
dest: Some(dest_place.clone()),
|
||||||
target: Some(next_block),
|
target: Some(next_block),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ mod Main {
|
||||||
pub fn main(argc: i32) -> i32 {
|
pub fn main(argc: i32) -> i32 {
|
||||||
let mut x: i32 = 2;
|
let mut x: i32 = 2;
|
||||||
x = 4;
|
x = 4;
|
||||||
|
a();
|
||||||
return x + 2;
|
return x + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue