Add IRFunction, mess with lifetimes
This commit is contained in:
		
							parent
							
								
									22ee941ad6
								
							
						
					
					
						commit
						9b5d8acdb4
					
				| @ -1,7 +1,5 @@ | |||||||
| // Arithmetic, function calls and imports! | // Arithmetic, function calls and imports! | ||||||
| 
 | 
 | ||||||
| import std::print; |  | ||||||
| 
 |  | ||||||
| fn main() { | fn main() { | ||||||
|     let test = 9; |     let test = 9; | ||||||
|     let simpleAdd = 2 + 2; |     let simpleAdd = 2 + 2; | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| use std::ffi::{CStr, CString}; | use std::ffi::{CStr, CString}; | ||||||
| use std::mem; | 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 { | fn into_cstring<T: Into<String>>(value: T) -> CString { | ||||||
|     let string = value.into(); |     let string = value.into(); | ||||||
| @ -44,30 +44,11 @@ pub struct IRModule<'a> { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<'a> 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 { |         unsafe { | ||||||
|             let module = |             let module = | ||||||
|                 LLVMModuleCreateWithNameInContext(into_cstring(name).as_ptr(), context.context); |                 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 } |             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; | 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 { | pub fn form_context() -> IRContext { | ||||||
|     IRContext::new() |     IRContext::new() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn from_statements<'a>( | pub fn from_statements( | ||||||
|     context: &'a mut IRContext, |     context: &mut IRContext, | ||||||
|     statements: Vec<TopLevelStatement>, |     statements: Vec<TopLevelStatement>, | ||||||
| ) -> Result<IRModule<'a>, Error> { | ) -> Result<IRModule, Error> { | ||||||
|     Ok(context.module("testmod".to_owned())) |     let mut module = context.module("testmod".to_owned()); | ||||||
|  |     for statement in statements { | ||||||
|  |         statement.codegen(&mut module); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Ok(module) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(thiserror::Error, Debug)] | impl TopLevelStatement { | ||||||
| pub enum Error {} |     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