Compiling if statements like half done

This commit is contained in:
greg 2017-01-10 03:33:02 -08:00
parent 12fbc51da1
commit 8c4f7e141a
2 changed files with 48 additions and 5 deletions

View File

@ -128,9 +128,9 @@ impl CodeGen for Expression {
let int_type = LLVMWrap::Int64TypeInContext(data.context); let int_type = LLVMWrap::Int64TypeInContext(data.context);
match self { match *self {
&Variable(ref name) => *data.variables.get(&**name).unwrap(), Variable(ref name) => *data.variables.get(&**name).unwrap(),
&BinExp(ref op, ref left, ref right) if **op == "=" => { BinExp(ref op, ref left, ref right) if **op == "=" => {
if let Variable(ref name) = **left { if let Variable(ref name) = **left {
let new_value = right.codegen(data); let new_value = right.codegen(data);
data.variables.insert((**name).clone(), new_value); data.variables.insert((**name).clone(), new_value);
@ -139,7 +139,7 @@ impl CodeGen for Expression {
panic!("Bad variable assignment") panic!("Bad variable assignment")
} }
} }
&BinExp(ref op, ref left, ref right) => { BinExp(ref op, ref left, ref right) => {
let lhs = left.codegen(data); let lhs = left.codegen(data);
let rhs = right.codegen(data); let rhs = right.codegen(data);
let generator = match op.as_ref().as_ref() { let generator = match op.as_ref().as_ref() {
@ -153,11 +153,35 @@ impl CodeGen for Expression {
generator(data.builder, lhs, rhs, "temp") generator(data.builder, lhs, rhs, "temp")
} }
&Number(ref n) => { Number(ref n) => {
let native_val = *n as u64; let native_val = *n as u64;
let int_value: LLVMValueRef = LLVMWrap::ConstInt(int_type, native_val, false); let int_value: LLVMValueRef = LLVMWrap::ConstInt(int_type, native_val, false);
int_value 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!(), _ => unimplemented!(),
} }
} }

View File

@ -2,6 +2,7 @@
#![allow(dead_code)] #![allow(dead_code)]
extern crate llvm_sys; extern crate llvm_sys;
use self::llvm_sys::LLVMIntPredicate;
use self::llvm_sys::prelude::*; use self::llvm_sys::prelude::*;
use self::llvm_sys::core; use self::llvm_sys::core;
use std::ptr; use std::ptr;
@ -132,6 +133,24 @@ pub fn BuildSRem(builder: LLVMBuilderRef,
unsafe { core::LLVMBuildSRem(builder, lhs, rhs, name.as_ptr()) } 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 { pub fn PrintModuleToFile(module: LLVMModuleRef, filename: &str) -> LLVMBool {
let out_file = CString::new(filename).unwrap(); let out_file = CString::new(filename).unwrap();
unsafe { core::LLVMPrintModuleToFile(module, out_file.as_ptr(), ptr::null_mut()) } unsafe { core::LLVMPrintModuleToFile(module, out_file.as_ptr(), ptr::null_mut()) }