Add IRFunction, mess with lifetimes
This commit is contained in:
		
							parent
							
								
									22ee941ad6
								
							
						
					
					
						commit
						9b5d8acdb4
					
				| @ -1,7 +1,5 @@ | ||||
| // Arithmetic, function calls and imports! | ||||
| 
 | ||||
| import std::print; | ||||
| 
 | ||||
| fn main() { | ||||
|     let test = 9; | ||||
|     let simpleAdd = 2 + 2; | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| use std::ffi::{CStr, CString}; | ||||
| use std::mem; | ||||
| 
 | ||||
| use llvm_sys::{core::*, prelude::*, LLVMBuilder, LLVMContext, LLVMModule}; | ||||
| use llvm_sys::{core::*, prelude::*, LLVMBuilder, LLVMContext, LLVMModule, LLVMType, LLVMValue}; | ||||
| 
 | ||||
| fn into_cstring<T: Into<String>>(value: T) -> CString { | ||||
|     let string = value.into(); | ||||
| @ -44,30 +44,11 @@ pub struct IRModule<'a> { | ||||
| } | ||||
| 
 | ||||
| impl<'a> IRModule<'a> { | ||||
|     fn new(context: &'a mut IRContext, name: String) -> IRModule<'a> { | ||||
|     fn new<'b: 'a>(context: &'b mut IRContext, name: String) -> IRModule<'a> { | ||||
|         unsafe { | ||||
|             let module = | ||||
|                 LLVMModuleCreateWithNameInContext(into_cstring(name).as_ptr(), context.context); | ||||
| 
 | ||||
|             // TODO, fix later!
 | ||||
| 
 | ||||
|             let t = LLVMInt32TypeInContext(context.context); | ||||
| 
 | ||||
|             let mut argts = []; | ||||
|             let func_type = LLVMFunctionType(t, argts.as_mut_ptr(), argts.len() as u32, 0); | ||||
| 
 | ||||
|             let anon_func = LLVMAddFunction(module, into_cstring("testfunc").as_ptr(), func_type); | ||||
| 
 | ||||
|             let blockref = | ||||
|                 LLVMCreateBasicBlockInContext(context.context, into_cstring("entryblock").as_ptr()); | ||||
|             LLVMPositionBuilderAtEnd(context.builder, blockref); | ||||
| 
 | ||||
|             // What is the last 1 ?
 | ||||
|             let val = LLVMConstInt(t, mem::transmute(3 as i64), 1); | ||||
| 
 | ||||
|             LLVMAppendExistingBasicBlock(anon_func, blockref); | ||||
|             LLVMBuildRet(context.builder, val); | ||||
| 
 | ||||
|             IRModule { context, module } | ||||
|         } | ||||
|     } | ||||
| @ -85,3 +66,49 @@ impl<'a> Drop for IRModule<'a> { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct IRFunction<'a, 'b> { | ||||
|     module: &'b mut IRModule<'a>, | ||||
|     /// Signature of the function
 | ||||
|     return_type: *mut LLVMType, | ||||
|     /// Signature of the function
 | ||||
|     func_type: *mut LLVMType, | ||||
|     /// The actual function
 | ||||
|     value: *mut LLVMValue, | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'b> IRFunction<'a, 'b> { | ||||
|     pub fn new(module: &'b mut IRModule<'a>) -> IRFunction<'a, 'b> { | ||||
|         unsafe { | ||||
|             // TODO, fix later!
 | ||||
| 
 | ||||
|             let return_type = LLVMInt32TypeInContext(module.context.context); | ||||
| 
 | ||||
|             let mut argts = []; | ||||
|             let func_type = | ||||
|                 LLVMFunctionType(return_type, argts.as_mut_ptr(), argts.len() as u32, 0); | ||||
| 
 | ||||
|             let function = | ||||
|                 LLVMAddFunction(module.module, into_cstring("testfunc").as_ptr(), func_type); | ||||
| 
 | ||||
|             let blockref = LLVMCreateBasicBlockInContext( | ||||
|                 module.context.context, | ||||
|                 into_cstring("entryblock").as_ptr(), | ||||
|             ); | ||||
|             LLVMPositionBuilderAtEnd(module.context.builder, blockref); | ||||
| 
 | ||||
|             // What is the last 1 ?
 | ||||
|             let return_value = LLVMConstInt(return_type, mem::transmute(3 as i64), 1); | ||||
| 
 | ||||
|             LLVMAppendExistingBasicBlock(function, blockref); | ||||
|             LLVMBuildRet(module.context.builder, return_value); | ||||
| 
 | ||||
|             IRFunction { | ||||
|                 module, | ||||
|                 return_type, | ||||
|                 func_type, | ||||
|                 value: function, | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,19 +1,39 @@ | ||||
| mod llvm; | ||||
| 
 | ||||
| use llvm::{IRContext, IRModule}; | ||||
| use llvm::{IRContext, IRFunction, IRModule}; | ||||
| 
 | ||||
| use crate::TopLevelStatement; | ||||
| use crate::{ast::FunctionDefinition, TopLevelStatement}; | ||||
| 
 | ||||
| #[derive(thiserror::Error, Debug)] | ||||
| pub enum Error {} | ||||
| 
 | ||||
| pub fn form_context() -> IRContext { | ||||
|     IRContext::new() | ||||
| } | ||||
| 
 | ||||
| pub fn from_statements<'a>( | ||||
|     context: &'a mut IRContext, | ||||
| pub fn from_statements( | ||||
|     context: &mut IRContext, | ||||
|     statements: Vec<TopLevelStatement>, | ||||
| ) -> Result<IRModule<'a>, Error> { | ||||
|     Ok(context.module("testmod".to_owned())) | ||||
| ) -> Result<IRModule, Error> { | ||||
|     let mut module = context.module("testmod".to_owned()); | ||||
|     for statement in statements { | ||||
|         statement.codegen(&mut module); | ||||
|     } | ||||
| 
 | ||||
|     Ok(module) | ||||
| } | ||||
| 
 | ||||
| #[derive(thiserror::Error, Debug)] | ||||
| pub enum Error {} | ||||
| impl TopLevelStatement { | ||||
|     fn codegen(&self, module: &mut IRModule) { | ||||
|         match self { | ||||
|             Self::FunctionDefinition(func) => func.codegen(module), | ||||
|             Self::Import(_) => panic!("not implemented"), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl FunctionDefinition { | ||||
|     fn codegen(&self, module: &mut IRModule) { | ||||
|         let function = IRFunction::new(module); | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user