Add the ability to call functions
This commit is contained in:
parent
5f93b7c9c2
commit
d0aa3e1410
@ -6,9 +6,16 @@ pub fn main() {
|
||||
|
||||
let mainfunc = IRFunction::new(&module, &"mainfunc".to_owned());
|
||||
|
||||
let secondary_func = IRFunction::new(&module, &"secondary".to_owned());
|
||||
|
||||
let secondary_block = IRBlock::new(&context, &"secondaryblock".to_owned());
|
||||
secondary_block.ret(&secondary_func, IRValue::from_const(&context, 54).into());
|
||||
|
||||
let block = IRBlock::new(&context, &"mainblock".to_owned());
|
||||
|
||||
let lhs_cmp = IRValue::from_const(&context, 100);
|
||||
let lhs_1 = IRValue::from_const(&context, 100);
|
||||
let lhs_2 = block.call(&secondary_func);
|
||||
let lhs_cmp = block.add(lhs_1.into(), lhs_2.into()).unwrap();
|
||||
let rhs_cmp = IRValue::from_const(&context, 200);
|
||||
|
||||
let compare = block.less_than(lhs_cmp.into(), rhs_cmp.into()).unwrap();
|
||||
|
@ -61,6 +61,8 @@ impl IRType for i32 {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IROpaqueValue(LLVMTypeRef, LLVMValueRef);
|
||||
|
||||
pub struct IRValue<T: IRType>(PhantomData<T>, IROpaqueValue);
|
||||
|
||||
impl<T: IRType> IRValue<T> {
|
||||
@ -85,8 +87,6 @@ impl<T: IRType> From<IRValue<T>> for IROpaqueValue {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IROpaqueValue(LLVMTypeRef, LLVMValueRef);
|
||||
|
||||
pub struct IRContext {
|
||||
context: *mut LLVMContext,
|
||||
builder: *mut LLVMBuilder,
|
||||
@ -209,8 +209,10 @@ impl<'a> Drop for IRModule<'a> {
|
||||
}
|
||||
|
||||
pub struct IRFunction<'a> {
|
||||
pub name: String,
|
||||
pub module: &'a IRModule<'a>,
|
||||
pub functionref: *mut LLVMValue,
|
||||
pub function_ref: *mut LLVMValue,
|
||||
pub function_type: *mut LLVMType,
|
||||
}
|
||||
|
||||
impl<'a> IRFunction<'a> {
|
||||
@ -222,12 +224,17 @@ impl<'a> IRFunction<'a> {
|
||||
let func_type =
|
||||
LLVMFunctionType(return_type, argts.as_mut_ptr(), argts.len() as u32, 0);
|
||||
|
||||
let functionref =
|
||||
let function_ref =
|
||||
LLVMAddFunction(module.module, into_cstring(name).as_ptr(), func_type);
|
||||
|
||||
let function_type =
|
||||
LLVMFunctionType(return_type, argts.as_mut_ptr(), argts.len() as u32, 0);
|
||||
|
||||
IRFunction {
|
||||
name: name.clone(),
|
||||
module,
|
||||
functionref,
|
||||
function_ref,
|
||||
function_type,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -253,6 +260,41 @@ impl<'a> IRBlock<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn call(&self, function: &IRFunction) -> IROpaqueValue {
|
||||
unsafe {
|
||||
let builder = self.context.builder;
|
||||
LLVMPositionBuilderAtEnd(builder, self.blockref);
|
||||
|
||||
// Add way to check and use parameters
|
||||
let mut args = [];
|
||||
|
||||
let value = LLVMBuildCall2(
|
||||
builder,
|
||||
function.function_type,
|
||||
function.function_ref,
|
||||
args.as_mut_ptr(),
|
||||
args.len() as u32,
|
||||
into_cstring(&function.name).as_ptr(),
|
||||
);
|
||||
IROpaqueValue(i32::llvm_type(&self.context), value)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add(&self, lhs: IROpaqueValue, rhs: IROpaqueValue) -> Result<IROpaqueValue, ()> {
|
||||
let IROpaqueValue(t1, lhs) = lhs;
|
||||
let IROpaqueValue(t2, rhs) = rhs;
|
||||
if t1 != t2 {
|
||||
Err(())
|
||||
} else {
|
||||
unsafe {
|
||||
let builder = self.context.builder;
|
||||
LLVMPositionBuilderAtEnd(builder, self.blockref);
|
||||
let value = LLVMBuildAdd(builder, lhs, rhs, c"add".as_ptr());
|
||||
Ok(IROpaqueValue(t1, value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn less_than(&self, lhs: IROpaqueValue, rhs: IROpaqueValue) -> Result<IRValue<bool>, ()> {
|
||||
let IROpaqueValue(t1, lhs) = lhs;
|
||||
let IROpaqueValue(t2, rhs) = rhs;
|
||||
@ -302,7 +344,7 @@ impl<'a> IRBlock<'a> {
|
||||
|
||||
unsafe fn append(mut self, function: &IRFunction<'a>) {
|
||||
unsafe {
|
||||
LLVMAppendExistingBasicBlock(function.functionref, self.blockref);
|
||||
LLVMAppendExistingBasicBlock(function.function_ref, self.blockref);
|
||||
self.inserted = true;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user