Function codegen sorta works

This commit is contained in:
greg 2017-01-14 17:19:11 -08:00
parent b9d1140264
commit 8f2d9b900b
2 changed files with 49 additions and 7 deletions

View File

@ -5,7 +5,7 @@ use std::collections::HashMap;
use self::llvm_sys::prelude::*;
use self::llvm_sys::{LLVMIntPredicate, LLVMRealPredicate};
use parser::{AST, Statement, Function, Expression, BinOp};
use parser::{AST, Statement, Function, Prototype, Expression, BinOp};
use llvm_wrap as LLVMWrap;
@ -60,7 +60,7 @@ fn compile_ast(ast: AST, filename: &str) {
let builder = LLVMWrap::CreateBuilderInContext(context);
let program_return_type = LLVMWrap::Int64TypeInContext(context);
let main_function_type = LLVMWrap::FunctionType(program_return_type, &Vec::new(), false);
let main_function_type = LLVMWrap::FunctionType(program_return_type, Vec::new(), false);
let main_function: LLVMValueRef = LLVMWrap::AddFunction(module, "main", main_function_type);
let mut data = CompilationData {
@ -116,9 +116,15 @@ impl CodeGen for Statement {
impl CodeGen for Function {
fn codegen(&self, data: &mut CompilationData) -> LLVMValueRef {
let function = self.prototype.codegen(data);
let ref body = self.body;
let int_type = LLVMWrap::Int64TypeInContext(data.context);
let mut ret = LLVMWrap::ConstInt(int_type, 0, false);
let return_type = LLVMWrap::Int64TypeInContext(data.context);
let mut ret = LLVMWrap::ConstInt(return_type, 0, false);
println!("Getting here");
for expr in body {
ret = expr.codegen(data);
}
@ -126,6 +132,29 @@ impl CodeGen for Function {
}
}
impl CodeGen for Prototype {
fn codegen(&self, data: &mut CompilationData) -> LLVMValueRef {
let num_args = self.parameters.len();
let return_type = LLVMWrap::Int64TypeInContext(data.context);
let mut arguments: Vec<LLVMTypeRef> = vec![];
for _ in 0..num_args {
arguments.push(LLVMWrap::Int64TypeInContext(data.context));
}
let function_type =
LLVMWrap::FunctionType(return_type,
arguments,
false);
let function = LLVMWrap::AddFunction(data.module,
&*self.name,
function_type);
function
}
}
impl CodeGen for Expression {
fn codegen(&self, data: &mut CompilationData) -> LLVMValueRef {
use self::BinOp::*;

View File

@ -34,20 +34,33 @@ pub fn AddFunction(module: LLVMModuleRef, name: &str, function_type: LLVMTypeRef
unsafe { core::LLVMAddFunction(module, c_name.as_ptr(), function_type) }
}
// NOTE this is incomplete
pub fn FunctionType(return_type: LLVMTypeRef,
param_types: &[LLVMTypeRef],
mut param_types: Vec<LLVMTypeRef>,
is_var_rag: bool)
-> LLVMTypeRef {
let len = param_types.len();
unsafe {
let pointer = param_types.as_mut_ptr();
core::LLVMFunctionType(return_type,
ptr::null_mut(),
pointer,
len as u32,
if is_var_rag { 1 } else { 0 })
}
}
pub fn GetNamedFunction(module: LLVMModuleRef,
name: &str) -> Option<LLVMValueRef> {
let c_name = CString::new(name).unwrap();
let ret = unsafe { core::LLVMGetNamedFunction(module, c_name.as_ptr()) };
if ret.is_null() {
None
} else {
Some(ret)
}
}
pub fn VoidTypeInContext(context: LLVMContextRef) -> LLVMTypeRef {
unsafe { core::LLVMVoidTypeInContext(context) }
}