From 7208fe962e66faf8aef46c12a81804a52eb81039 Mon Sep 17 00:00:00 2001 From: sofia Date: Wed, 21 Aug 2024 22:14:32 +0300 Subject: [PATCH] Read return and function name from signature --- examples/reid/easy.reid | 7 +------ src/codegen/llvm.rs | 32 +++++++++++++++++++------------- src/codegen/mod.rs | 35 ++++++++++++++++++++++++++++++----- 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/examples/reid/easy.reid b/examples/reid/easy.reid index 87362f3..2dc010c 100644 --- a/examples/reid/easy.reid +++ b/examples/reid/easy.reid @@ -1,10 +1,5 @@ // Arithmetic, function calls and imports! fn main() { - let test = 9; - let simpleAdd = 2 + 2; - let simpleMult = 7 * 2; - let arithmetic = 3 + 2 * 5 + 1 * 2; - - return arithmetic + simpleMult * arithmetic; + return 5; } \ No newline at end of file diff --git a/src/codegen/llvm.rs b/src/codegen/llvm.rs index 5b144db..04dd0c8 100644 --- a/src/codegen/llvm.rs +++ b/src/codegen/llvm.rs @@ -5,6 +5,8 @@ use llvm_sys::{ core::*, prelude::*, LLVMBasicBlock, LLVMBuilder, LLVMContext, LLVMModule, LLVMType, LLVMValue, }; +use crate::ast; + fn into_cstring>(value: T) -> CString { let string = value.into(); 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> { - 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 { // TODO, fix later! @@ -102,8 +104,7 @@ impl<'a, 'b> IRFunction<'a, 'b> { 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 function = LLVMAddFunction(module.module, into_cstring(name).as_ptr(), func_type); IRFunction { module, @@ -156,15 +157,20 @@ pub struct IRValue { } impl IRValue { - pub fn const_i32(value: i32, block: &mut IRBlock) -> Self { - let ir_type = IRType::I32; - unsafe { - let ir_value = LLVMConstInt( - ir_type.in_context(block.function.module.context), - mem::transmute(3 as i64), - 1, - ); - return IRValue { ir_type, ir_value }; - } + pub fn from_literal(literal: &ast::Literal, block: &mut IRBlock) -> Self { + use ast::Literal; + match literal { + Literal::I32(v) => { + let ir_type = IRType::I32; + unsafe { + let ir_value = LLVMConstInt( + ir_type.in_context(block.function.module.context), + mem::transmute(*v as i64), + 1, + ); + return IRValue { ir_type, ir_value }; + } + } + }; } } diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index d82c086..c47a190 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -2,7 +2,10 @@ mod llvm; use llvm::{IRBlock, IRContext, IRFunction, IRModule, IRValue}; -use crate::{ast::FunctionDefinition, TopLevelStatement}; +use crate::{ + ast::{Block, Expression, ExpressionKind, FunctionDefinition}, + TopLevelStatement, +}; #[derive(thiserror::Error, Debug)] pub enum Error {} @@ -34,9 +37,31 @@ impl TopLevelStatement { impl FunctionDefinition { fn codegen(&self, module: &mut IRModule) { - let mut function = IRFunction::new(module); - let mut block = IRBlock::new(&mut function); - let value = IRValue::const_i32(3, &mut block); - block.add_return(Some(value)) + let FunctionDefinition(signature, block, _) = self; + let mut function = IRFunction::new(&signature.name, module); + block.codegen(&mut function) + } +} + +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"), + } } }