Read return and function name from signature

This commit is contained in:
Sofia 2024-08-21 22:14:32 +03:00
parent 525dab2147
commit 7208fe962e
3 changed files with 50 additions and 24 deletions

View File

@ -1,10 +1,5 @@
// Arithmetic, function calls and imports! // Arithmetic, function calls and imports!
fn main() { fn main() {
let test = 9; return 5;
let simpleAdd = 2 + 2;
let simpleMult = 7 * 2;
let arithmetic = 3 + 2 * 5 + 1 * 2;
return arithmetic + simpleMult * arithmetic;
} }

View File

@ -5,6 +5,8 @@ use llvm_sys::{
core::*, prelude::*, LLVMBasicBlock, LLVMBuilder, LLVMContext, LLVMModule, LLVMType, LLVMValue, core::*, prelude::*, LLVMBasicBlock, LLVMBuilder, LLVMContext, LLVMModule, LLVMType, LLVMValue,
}; };
use crate::ast;
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();
unsafe { CString::from_vec_with_nul_unchecked((string + "\0").into_bytes()) } unsafe { CString::from_vec_with_nul_unchecked((string + "\0").into_bytes()) }
@ -92,7 +94,7 @@ pub struct IRFunction<'a, 'b> {
} }
impl<'a, 'b> IRFunction<'a, 'b> { impl<'a, 'b> IRFunction<'a, 'b> {
pub fn new(module: &'b mut IRModule<'a>) -> IRFunction<'a, 'b> { pub fn new(name: &String, module: &'b mut IRModule<'a>) -> IRFunction<'a, 'b> {
unsafe { unsafe {
// TODO, fix later! // TODO, fix later!
@ -102,8 +104,7 @@ impl<'a, 'b> IRFunction<'a, 'b> {
let func_type = let func_type =
LLVMFunctionType(return_type, argts.as_mut_ptr(), argts.len() as u32, 0); LLVMFunctionType(return_type, argts.as_mut_ptr(), argts.len() as u32, 0);
let function = let function = LLVMAddFunction(module.module, into_cstring(name).as_ptr(), func_type);
LLVMAddFunction(module.module, into_cstring("testfunc").as_ptr(), func_type);
IRFunction { IRFunction {
module, module,
@ -156,15 +157,20 @@ pub struct IRValue {
} }
impl IRValue { impl IRValue {
pub fn const_i32(value: i32, block: &mut IRBlock) -> Self { pub fn from_literal(literal: &ast::Literal, block: &mut IRBlock) -> Self {
use ast::Literal;
match literal {
Literal::I32(v) => {
let ir_type = IRType::I32; let ir_type = IRType::I32;
unsafe { unsafe {
let ir_value = LLVMConstInt( let ir_value = LLVMConstInt(
ir_type.in_context(block.function.module.context), ir_type.in_context(block.function.module.context),
mem::transmute(3 as i64), mem::transmute(*v as i64),
1, 1,
); );
return IRValue { ir_type, ir_value }; return IRValue { ir_type, ir_value };
} }
} }
};
}
} }

View File

@ -2,7 +2,10 @@ mod llvm;
use llvm::{IRBlock, IRContext, IRFunction, IRModule, IRValue}; use llvm::{IRBlock, IRContext, IRFunction, IRModule, IRValue};
use crate::{ast::FunctionDefinition, TopLevelStatement}; use crate::{
ast::{Block, Expression, ExpressionKind, FunctionDefinition},
TopLevelStatement,
};
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
pub enum Error {} pub enum Error {}
@ -34,9 +37,31 @@ impl TopLevelStatement {
impl FunctionDefinition { impl FunctionDefinition {
fn codegen(&self, module: &mut IRModule) { fn codegen(&self, module: &mut IRModule) {
let mut function = IRFunction::new(module); let FunctionDefinition(signature, block, _) = self;
let mut block = IRBlock::new(&mut function); let mut function = IRFunction::new(&signature.name, module);
let value = IRValue::const_i32(3, &mut block); block.codegen(&mut function)
block.add_return(Some(value)) }
}
impl Block {
fn codegen(&self, function: &mut IRFunction) {
let mut block = IRBlock::new(function);
if let Some((_, return_exp)) = &self.1 {
let value = return_exp.codegen(&mut block);
block.add_return(Some(value))
}
}
}
impl Expression {
fn codegen(&self, block: &mut IRBlock) -> IRValue {
let Expression(kind, _) = self;
use ExpressionKind::*;
match kind {
Literal(lit) => IRValue::from_literal(lit, block),
_ => panic!("expression type not supported"),
}
} }
} }