Function codegen sorta works
This commit is contained in:
parent
b9d1140264
commit
8f2d9b900b
@ -5,7 +5,7 @@ use std::collections::HashMap;
|
|||||||
use self::llvm_sys::prelude::*;
|
use self::llvm_sys::prelude::*;
|
||||||
use self::llvm_sys::{LLVMIntPredicate, LLVMRealPredicate};
|
use self::llvm_sys::{LLVMIntPredicate, LLVMRealPredicate};
|
||||||
|
|
||||||
use parser::{AST, Statement, Function, Expression, BinOp};
|
use parser::{AST, Statement, Function, Prototype, Expression, BinOp};
|
||||||
|
|
||||||
use llvm_wrap as LLVMWrap;
|
use llvm_wrap as LLVMWrap;
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ fn compile_ast(ast: AST, filename: &str) {
|
|||||||
let builder = LLVMWrap::CreateBuilderInContext(context);
|
let builder = LLVMWrap::CreateBuilderInContext(context);
|
||||||
|
|
||||||
let program_return_type = LLVMWrap::Int64TypeInContext(context);
|
let program_return_type = LLVMWrap::Int64TypeInContext(context);
|
||||||
let main_function_type = LLVMWrap::FunctionType(program_return_type, &Vec::new(), false);
|
let main_function_type = LLVMWrap::FunctionType(program_return_type, Vec::new(), false);
|
||||||
let main_function: LLVMValueRef = LLVMWrap::AddFunction(module, "main", main_function_type);
|
let main_function: LLVMValueRef = LLVMWrap::AddFunction(module, "main", main_function_type);
|
||||||
|
|
||||||
let mut data = CompilationData {
|
let mut data = CompilationData {
|
||||||
@ -116,9 +116,15 @@ impl CodeGen for Statement {
|
|||||||
|
|
||||||
impl CodeGen for Function {
|
impl CodeGen for Function {
|
||||||
fn codegen(&self, data: &mut CompilationData) -> LLVMValueRef {
|
fn codegen(&self, data: &mut CompilationData) -> LLVMValueRef {
|
||||||
|
|
||||||
|
let function = self.prototype.codegen(data);
|
||||||
let ref body = self.body;
|
let ref body = self.body;
|
||||||
let int_type = LLVMWrap::Int64TypeInContext(data.context);
|
|
||||||
let mut ret = LLVMWrap::ConstInt(int_type, 0, false);
|
let return_type = LLVMWrap::Int64TypeInContext(data.context);
|
||||||
|
let mut ret = LLVMWrap::ConstInt(return_type, 0, false);
|
||||||
|
|
||||||
|
println!("Getting here");
|
||||||
|
|
||||||
for expr in body {
|
for expr in body {
|
||||||
ret = expr.codegen(data);
|
ret = expr.codegen(data);
|
||||||
}
|
}
|
||||||
@ -126,6 +132,29 @@ impl CodeGen for Function {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl CodeGen for Prototype {
|
||||||
|
fn codegen(&self, data: &mut CompilationData) -> LLVMValueRef {
|
||||||
|
let num_args = self.parameters.len();
|
||||||
|
let return_type = LLVMWrap::Int64TypeInContext(data.context);
|
||||||
|
let mut arguments: Vec<LLVMTypeRef> = vec![];
|
||||||
|
|
||||||
|
for _ in 0..num_args {
|
||||||
|
arguments.push(LLVMWrap::Int64TypeInContext(data.context));
|
||||||
|
}
|
||||||
|
|
||||||
|
let function_type =
|
||||||
|
LLVMWrap::FunctionType(return_type,
|
||||||
|
arguments,
|
||||||
|
false);
|
||||||
|
|
||||||
|
let function = LLVMWrap::AddFunction(data.module,
|
||||||
|
&*self.name,
|
||||||
|
function_type);
|
||||||
|
|
||||||
|
function
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl CodeGen for Expression {
|
impl CodeGen for Expression {
|
||||||
fn codegen(&self, data: &mut CompilationData) -> LLVMValueRef {
|
fn codegen(&self, data: &mut CompilationData) -> LLVMValueRef {
|
||||||
use self::BinOp::*;
|
use self::BinOp::*;
|
||||||
|
@ -34,20 +34,33 @@ pub fn AddFunction(module: LLVMModuleRef, name: &str, function_type: LLVMTypeRef
|
|||||||
unsafe { core::LLVMAddFunction(module, c_name.as_ptr(), function_type) }
|
unsafe { core::LLVMAddFunction(module, c_name.as_ptr(), function_type) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE this is incomplete
|
|
||||||
pub fn FunctionType(return_type: LLVMTypeRef,
|
pub fn FunctionType(return_type: LLVMTypeRef,
|
||||||
param_types: &[LLVMTypeRef],
|
mut param_types: Vec<LLVMTypeRef>,
|
||||||
is_var_rag: bool)
|
is_var_rag: bool)
|
||||||
-> LLVMTypeRef {
|
-> LLVMTypeRef {
|
||||||
let len = param_types.len();
|
let len = param_types.len();
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let pointer = param_types.as_mut_ptr();
|
||||||
core::LLVMFunctionType(return_type,
|
core::LLVMFunctionType(return_type,
|
||||||
ptr::null_mut(),
|
pointer,
|
||||||
len as u32,
|
len as u32,
|
||||||
if is_var_rag { 1 } else { 0 })
|
if is_var_rag { 1 } else { 0 })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn GetNamedFunction(module: LLVMModuleRef,
|
||||||
|
name: &str) -> Option<LLVMValueRef> {
|
||||||
|
|
||||||
|
let c_name = CString::new(name).unwrap();
|
||||||
|
let ret = unsafe { core::LLVMGetNamedFunction(module, c_name.as_ptr()) };
|
||||||
|
|
||||||
|
if ret.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(ret)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn VoidTypeInContext(context: LLVMContextRef) -> LLVMTypeRef {
|
pub fn VoidTypeInContext(context: LLVMContextRef) -> LLVMTypeRef {
|
||||||
unsafe { core::LLVMVoidTypeInContext(context) }
|
unsafe { core::LLVMVoidTypeInContext(context) }
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user