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_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 {
|
||||
|
|
|
@ -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)),
|
||||
|
|
|
@ -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),
|
||||
};
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ mod Main {
|
|||
pub fn main(argc: i32) -> i32 {
|
||||
let mut x: i32 = 2;
|
||||
x = 4;
|
||||
a();
|
||||
return x + 2;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue