Execute statements
This commit is contained in:
parent
0eb2b9ec04
commit
bcc2bf937f
1 changed files with 54 additions and 9 deletions
|
@ -1,37 +1,82 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use inkwell::{
|
use inkwell::{
|
||||||
|
builder::Builder,
|
||||||
context::Context,
|
context::Context,
|
||||||
module::Module,
|
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 {
|
impl Expr {
|
||||||
pub fn into_llvm_type<'ctx>(
|
pub fn into_llvm<'ctx>(
|
||||||
&self,
|
&self,
|
||||||
context: &'ctx Context,
|
context: &'ctx Context,
|
||||||
) -> AnyTypeEnum<'ctx> {
|
builder: &Builder,
|
||||||
|
) -> Result<BasicValueEnum<'ctx>> {
|
||||||
match self {
|
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> {
|
pub fn convert(context: &mut Context, program: Vec<Decl>) -> Result<Module> {
|
||||||
let module = context.create_module("program");
|
let module = context.create_module("program");
|
||||||
let builder = context.create_builder();
|
let builder = context.create_builder();
|
||||||
|
|
||||||
for func in program.iter().filter_map(Decl::unwrap_func) {
|
for func in program.iter().filter_map(Decl::unwrap_func) {
|
||||||
let return_ty = func.return_ty.into_llvm_type(context);
|
let return_ty = func.return_ty.into_llvm_basic_type(context);
|
||||||
let llvm_func_ty = return_ty.fn_type();
|
let llvm_func_ty = fn_type_basic(return_ty, &[], false);
|
||||||
|
|
||||||
let llvm_func = module.add_function(&func.name, llvm_func_ty, None);
|
let llvm_func = module.add_function(&func.name, llvm_func_ty, None);
|
||||||
let entry_block = context.append_basic_block(llvm_func, "entry");
|
let entry_block = context.append_basic_block(llvm_func, "entry");
|
||||||
|
|
||||||
builder.position_at_end(entry_block);
|
builder.position_at_end(entry_block);
|
||||||
|
|
||||||
builder.build_return(None);
|
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)
|
Ok(module)
|
||||||
|
|
Loading…
Reference in a new issue