Execute statements
This commit is contained in:
parent
0eb2b9ec04
commit
bcc2bf937f
1 changed files with 54 additions and 9 deletions
|
@ -1,38 +1,83 @@
|
|||
use anyhow::Result;
|
||||
use inkwell::{
|
||||
builder::Builder,
|
||||
context::Context,
|
||||
module::Module,
|
||||
types::{AnyType, AnyTypeEnum},
|
||||
types::{AnyTypeEnum, BasicMetadataTypeEnum, BasicTypeEnum, FunctionType},
|
||||
values::{
|
||||
AnyValue, AnyValueEnum, BasicValue, BasicValueEnum, FunctionValue, IntValue,
|
||||
},
|
||||
};
|
||||
|
||||
use super::{Decl, Type};
|
||||
use super::{Decl, Expr, Stmt, Type};
|
||||
|
||||
impl Type {
|
||||
pub fn into_llvm_type<'ctx>(
|
||||
impl Expr {
|
||||
pub fn into_llvm<'ctx>(
|
||||
&self,
|
||||
context: &'ctx Context,
|
||||
) -> AnyTypeEnum<'ctx> {
|
||||
builder: &Builder,
|
||||
) -> Result<BasicValueEnum<'ctx>> {
|
||||
match self {
|
||||
Type::Int => AnyTypeEnum::IntType(context.i64_type()),
|
||||
Expr::Int(n) => Ok(BasicValueEnum::IntValue(
|
||||
context.i64_type().const_int(*n as u64, false),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Type {
|
||||
pub fn into_llvm_basic_type<'ctx>(
|
||||
&self,
|
||||
context: &'ctx Context,
|
||||
) -> BasicTypeEnum<'ctx> {
|
||||
match self {
|
||||
Type::Int => BasicTypeEnum::IntType(context.i64_type()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fn_type_basic<'ctx>(
|
||||
return_ty: BasicTypeEnum<'ctx>,
|
||||
args: &[BasicMetadataTypeEnum<'ctx>],
|
||||
is_var_args: bool,
|
||||
) -> FunctionType<'ctx> {
|
||||
match return_ty {
|
||||
BasicTypeEnum::ArrayType(ty) => ty.fn_type(args, is_var_args),
|
||||
BasicTypeEnum::FloatType(ty) => ty.fn_type(args, is_var_args),
|
||||
BasicTypeEnum::IntType(ty) => ty.fn_type(args, is_var_args),
|
||||
BasicTypeEnum::PointerType(ty) => ty.fn_type(args, is_var_args),
|
||||
BasicTypeEnum::StructType(ty) => ty.fn_type(args, is_var_args),
|
||||
BasicTypeEnum::VectorType(ty) => ty.fn_type(args, is_var_args),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn convert(context: &mut Context, program: Vec<Decl>) -> Result<Module> {
|
||||
let module = context.create_module("program");
|
||||
let builder = context.create_builder();
|
||||
|
||||
for func in program.iter().filter_map(Decl::unwrap_func) {
|
||||
let return_ty = func.return_ty.into_llvm_type(context);
|
||||
let llvm_func_ty = return_ty.fn_type();
|
||||
let return_ty = func.return_ty.into_llvm_basic_type(context);
|
||||
let llvm_func_ty = fn_type_basic(return_ty, &[], false);
|
||||
|
||||
let llvm_func = module.add_function(&func.name, llvm_func_ty, None);
|
||||
let entry_block = context.append_basic_block(llvm_func, "entry");
|
||||
|
||||
builder.position_at_end(entry_block);
|
||||
|
||||
for stmt in func.stmts.iter() {
|
||||
match stmt {
|
||||
Stmt::Return(ret_val) => {
|
||||
if let Some(ret_val) = ret_val {
|
||||
let value = ret_val.into_llvm(context, &builder)?;
|
||||
builder.build_return(Some(&value));
|
||||
} else {
|
||||
builder.build_return(None);
|
||||
}
|
||||
println!("Emitted return.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(module)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue