From 748a85db0260f79d7479c400119d36b8ef4282cc Mon Sep 17 00:00:00 2001 From: greg Date: Sun, 15 Jan 2017 07:23:53 -0800 Subject: [PATCH] Compiling functions half-works --- compile.schala | 7 ++++++- src/compilation.rs | 17 +++++++++++++++-- src/llvm_wrap.rs | 31 ++++++++++++++++++++++++++++++- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/compile.schala b/compile.schala index 89c351d..721879b 100644 --- a/compile.schala +++ b/compile.schala @@ -1,2 +1,7 @@ -8 < 2 +fn hella(a, b) { + a + b +} + + +2 + 8 diff --git a/src/compilation.rs b/src/compilation.rs index ebb7859..714429e 100644 --- a/src/compilation.rs +++ b/src/compilation.rs @@ -117,13 +117,21 @@ impl CodeGen for Statement { impl CodeGen for Function { fn codegen(&self, data: &mut CompilationData) -> LLVMValueRef { + /* should have a check here for function already being defined */ let function = self.prototype.codegen(data); let ref body = self.body; let return_type = LLVMWrap::Int64TypeInContext(data.context); let mut ret = LLVMWrap::ConstInt(return_type, 0, false); - println!("Getting here"); + let block = LLVMWrap::AppendBasicBlockInContext(data.context, function, "entry"); + LLVMWrap::PositionBuilderAtEnd(data.builder, block); + + //insert function params into variables + for value in LLVMWrap::GetParams(function) { + let name = LLVMWrap::GetValueName(value); + data.variables.insert(name, value); + } for expr in body { ret = expr.codegen(data); @@ -151,6 +159,11 @@ impl CodeGen for Prototype { &*self.name, function_type); + for (index, param) in LLVMWrap::GetParams(function).iter().enumerate() { + let name = self.parameters.get(index).expect(&format!("Failed this check at index {}", index)); + LLVMWrap::SetValueName(*param, name); + } + function } } @@ -164,7 +177,7 @@ impl CodeGen for Expression { let zero = LLVMWrap::ConstInt(int_type, 0, false); match *self { - Variable(ref name) => *data.variables.get(&**name).unwrap(), + Variable(ref name) => *data.variables.get(&**name).expect(&format!("Can't find variable {}", name)), BinExp(Assign, ref left, ref right) => { if let Variable(ref name) = **left { let new_value = right.codegen(data); diff --git a/src/llvm_wrap.rs b/src/llvm_wrap.rs index e4e8646..a622ef7 100644 --- a/src/llvm_wrap.rs +++ b/src/llvm_wrap.rs @@ -6,7 +6,8 @@ use self::llvm_sys::{LLVMIntPredicate, LLVMRealPredicate}; use self::llvm_sys::prelude::*; use self::llvm_sys::core; use std::ptr; -use std::ffi::CString; +use std::ffi::{CString, CStr}; +use std::os::raw::c_char; pub fn create_context() -> LLVMContextRef { unsafe { core::LLVMContextCreate() } @@ -175,6 +176,34 @@ pub fn AddIncoming(phi: LLVMValueRef, incoming_values: *mut LLVMValueRef, incomi unsafe { core::LLVMAddIncoming(phi, incoming_values, incoming_blocks, count) } } +pub fn SetValueName(value: LLVMValueRef, name: &str) { + let name = CString::new(name).unwrap(); + unsafe { + core::LLVMSetValueName(value, name.as_ptr()) + } +} + +pub fn GetValueName(value: LLVMValueRef) -> String { + unsafe { + let name_ptr: *const c_char = core::LLVMGetValueName(value); + CStr::from_ptr(name_ptr).to_string_lossy().into_owned() + } +} + +pub fn GetParams(function: LLVMValueRef) -> Vec { + let size = CountParams(function); + unsafe { + let mut container = Vec::with_capacity(size); + let p = container.as_mut_ptr(); + core::LLVMGetParams(function, p); + Vec::from_raw_parts(p, size, size) + } +} + +pub fn CountParams(function: LLVMValueRef) -> usize { + unsafe { core::LLVMCountParams(function) as usize } +} + pub fn BuildFCmp(builder: LLVMBuilderRef, op: LLVMRealPredicate, lhs: LLVMValueRef,