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);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
Ok(module)
|
||||||
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