From 8f2d9b900bcbf78b946b335cbf07ea2d8145aaaa Mon Sep 17 00:00:00 2001 From: greg Date: Sat, 14 Jan 2017 17:19:11 -0800 Subject: [PATCH] Function codegen sorta works --- src/compilation.rs | 37 +++++++++++++++++++++++++++++++++---- src/llvm_wrap.rs | 19 ++++++++++++++++--- 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/compilation.rs b/src/compilation.rs index 2aed138..ebb7859 100644 --- a/src/compilation.rs +++ b/src/compilation.rs @@ -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 = 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::*; diff --git a/src/llvm_wrap.rs b/src/llvm_wrap.rs index 1619381..e4e8646 100644 --- a/src/llvm_wrap.rs +++ b/src/llvm_wrap.rs @@ -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, 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 { + + 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) } }