diff --git a/src/compilation.rs b/src/compilation.rs index d742eae..c23b939 100644 --- a/src/compilation.rs +++ b/src/compilation.rs @@ -128,9 +128,9 @@ impl CodeGen for Expression { let int_type = LLVMWrap::Int64TypeInContext(data.context); - match self { - &Variable(ref name) => *data.variables.get(&**name).unwrap(), - &BinExp(ref op, ref left, ref right) if **op == "=" => { + match *self { + Variable(ref name) => *data.variables.get(&**name).unwrap(), + BinExp(ref op, ref left, ref right) if **op == "=" => { if let Variable(ref name) = **left { let new_value = right.codegen(data); data.variables.insert((**name).clone(), new_value); @@ -139,7 +139,7 @@ impl CodeGen for Expression { panic!("Bad variable assignment") } } - &BinExp(ref op, ref left, ref right) => { + BinExp(ref op, ref left, ref right) => { let lhs = left.codegen(data); let rhs = right.codegen(data); let generator = match op.as_ref().as_ref() { @@ -153,11 +153,35 @@ impl CodeGen for Expression { generator(data.builder, lhs, rhs, "temp") } - &Number(ref n) => { + Number(ref n) => { let native_val = *n as u64; let int_value: LLVMValueRef = LLVMWrap::ConstInt(int_type, native_val, false); int_value } + Conditional(ref test, ref then_block, ref else_block) => { + let condition_value = test.codegen(data); + let zero = LLVMWrap::ConstInt(int_type, 0, false); + let is_nonzero = LLVMWrap::BuildICmp(data.builder, + llvm_sys::LLVMIntPredicate::LLVMIntNE, + condition_value, + zero, + "is_nonzero"); + + let func = 4; + let then_block = LLVMWrap::AppendBasicBlockInContext(data.context, + func, + "entry"); + let else_block = LLVMWrap::AppendBasicBlockInContext(data.context, + func, + "entry"); + let merge_block = LLVMWrap::AppendBasicBlockInContext(data.context, + func, + "entry"); + //LLVMWrap::BuildCondBr(data.builder, is_nonzero, g + + unimplemented!() + + } _ => unimplemented!(), } } diff --git a/src/llvm_wrap.rs b/src/llvm_wrap.rs index f22396a..ec15f21 100644 --- a/src/llvm_wrap.rs +++ b/src/llvm_wrap.rs @@ -2,6 +2,7 @@ #![allow(dead_code)] extern crate llvm_sys; +use self::llvm_sys::LLVMIntPredicate; use self::llvm_sys::prelude::*; use self::llvm_sys::core; use std::ptr; @@ -132,6 +133,24 @@ pub fn BuildSRem(builder: LLVMBuilderRef, unsafe { core::LLVMBuildSRem(builder, lhs, rhs, name.as_ptr()) } } +pub fn BuildCondBr(builder: LLVMBuilderRef, + if_expr: LLVMValueRef, + then_expr: LLVMBasicBlockRef, + else_expr: LLVMBasicBlockRef) -> LLVMValueRef { + + + unsafe { core::LLVMBuildCondBr(builder, if_expr, then_expr, else_expr) } +} + +pub fn BuildICmp(builder: LLVMBuilderRef, + op: LLVMIntPredicate, + lhs: LLVMValueRef, + rhs: LLVMValueRef, + name: &str) -> LLVMValueRef { + let name = CString::new(name).unwrap(); + unsafe { core::LLVMBuildICmp(builder, op, lhs, rhs, name.as_ptr()) } +} + pub fn PrintModuleToFile(module: LLVMModuleRef, filename: &str) -> LLVMBool { let out_file = CString::new(filename).unwrap(); unsafe { core::LLVMPrintModuleToFile(module, out_file.as_ptr(), ptr::null_mut()) }