Restructure a bit

This commit is contained in:
Sofia 2024-08-25 22:29:45 +03:00
parent 6a4c30e49e
commit 8defa39b31
3 changed files with 45 additions and 39 deletions

View File

@ -5,6 +5,10 @@ fn main() {
let simpleAdd = 2 + 2; let simpleAdd = 2 + 2;
let simpleMult = 7 * 2; // 14 let simpleMult = 7 * 2; // 14
let arithmetic = 3 + 2 * 5 + 1 * 2; // 15 let arithmetic = 3 + 2 * 5 + 1 * 2; // 15
if simpleAdd < test {
return 3;
}
return arithmetic + simpleMult * arithmetic; return arithmetic + simpleMult * arithmetic;
} }

View File

@ -24,7 +24,7 @@ pub enum IRType {
} }
impl IRType { impl IRType {
fn in_context(&self, context: &mut IRContext) -> *mut LLVMType { fn in_context(&self, context: &IRContext) -> *mut LLVMType {
use IRType::*; use IRType::*;
unsafe { unsafe {
return match self { return match self {
@ -38,14 +38,14 @@ impl IRType {
pub struct IRValue(pub IRType, *mut LLVMValue); pub struct IRValue(pub IRType, *mut LLVMValue);
impl IRValue { impl IRValue {
pub fn from_literal(literal: &ast::Literal, block: &mut IRBlock) -> Self { pub fn from_literal(literal: &ast::Literal, module: &IRModule) -> Self {
use ast::Literal; use ast::Literal;
match literal { match literal {
Literal::I32(v) => { 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(module.context),
mem::transmute(*v as i64), mem::transmute(*v as i64),
1, 1,
); );
@ -116,13 +116,13 @@ impl<'a> Drop for IRModule<'a> {
} }
pub struct IRFunction<'a, 'b> { pub struct IRFunction<'a, 'b> {
module: &'b mut IRModule<'a>, pub module: &'b IRModule<'a>,
/// The actual function /// The actual function
value: *mut LLVMValue, value: *mut LLVMValue,
} }
impl<'a, 'b> IRFunction<'a, 'b> { impl<'a, 'b> IRFunction<'a, 'b> {
pub fn new(name: &String, module: &'b mut IRModule<'a>) -> IRFunction<'a, 'b> { pub fn new(name: &String, module: &'b IRModule<'a>) -> IRFunction<'a, 'b> {
unsafe { unsafe {
// TODO, fix later! // TODO, fix later!
@ -140,23 +140,26 @@ impl<'a, 'b> IRFunction<'a, 'b> {
} }
} }
} }
pub fn attach(&mut self, block: IRBlock) {
unsafe { LLVMAppendExistingBasicBlock(self.value, block.blockref) }
}
} }
pub struct IRBlock<'a, 'b, 'c> { pub struct IRBlock<'a, 'b> {
function: &'a mut IRFunction<'b, 'c>, pub module: &'b IRModule<'a>,
blockref: *mut LLVMBasicBlock, blockref: *mut LLVMBasicBlock,
} }
impl<'a, 'b, 'c> IRBlock<'a, 'b, 'c> { impl<'a, 'b, 'c> IRBlock<'a, 'b> {
pub fn new(function: &'a mut IRFunction<'b, 'c>) -> IRBlock<'a, 'b, 'c> { pub fn new(module: &'b IRModule<'a>) -> IRBlock<'a, 'b> {
unsafe { unsafe {
let blockref = LLVMCreateBasicBlockInContext( let blockref = LLVMCreateBasicBlockInContext(
function.module.context.context, module.context.context,
into_cstring("entryblock").as_ptr(), into_cstring("entryblock").as_ptr(),
); );
LLVMPositionBuilderAtEnd(function.module.context.builder, blockref);
IRBlock { function, blockref } IRBlock { module, blockref }
} }
} }
@ -166,11 +169,12 @@ impl<'a, 'b, 'c> IRBlock<'a, 'b, 'c> {
IRValue(rhs_t, rhs_v): IRValue, IRValue(rhs_t, rhs_v): IRValue,
) -> Result<IRValue, Error> { ) -> Result<IRValue, Error> {
unsafe { unsafe {
LLVMPositionBuilderAtEnd(self.module.context.builder, self.blockref);
if lhs_t == rhs_t { if lhs_t == rhs_t {
Ok(IRValue( Ok(IRValue(
lhs_t, lhs_t,
LLVMBuildAdd( LLVMBuildAdd(
self.function.module.context.builder, self.module.context.builder,
lhs_v, lhs_v,
rhs_v, rhs_v,
c"tmpadd".as_ptr(), c"tmpadd".as_ptr(),
@ -188,11 +192,12 @@ impl<'a, 'b, 'c> IRBlock<'a, 'b, 'c> {
IRValue(rhs_t, rhs_v): IRValue, IRValue(rhs_t, rhs_v): IRValue,
) -> Result<IRValue, Error> { ) -> Result<IRValue, Error> {
unsafe { unsafe {
LLVMPositionBuilderAtEnd(self.module.context.builder, self.blockref);
if lhs_t == rhs_t { if lhs_t == rhs_t {
Ok(IRValue( Ok(IRValue(
lhs_t, lhs_t,
LLVMBuildMul( LLVMBuildMul(
self.function.module.context.builder, self.module.context.builder,
lhs_v, lhs_v,
rhs_v, rhs_v,
c"tmpadd".as_ptr(), c"tmpadd".as_ptr(),
@ -204,21 +209,14 @@ impl<'a, 'b, 'c> IRBlock<'a, 'b, 'c> {
} }
} }
pub fn add_return(self, value: Option<IRValue>) { pub fn add_return(&mut self, value: Option<IRValue>) {
unsafe { unsafe {
LLVMPositionBuilderAtEnd(self.module.context.builder, self.blockref);
if let Some(IRValue(_, value)) = value { if let Some(IRValue(_, value)) = value {
LLVMBuildRet(self.function.module.context.builder, value); LLVMBuildRet(self.module.context.builder, value);
} else { } else {
LLVMBuildRetVoid(self.function.module.context.builder); LLVMBuildRetVoid(self.module.context.builder);
} }
} }
} }
} }
impl<'a, 'b, 'c> Drop for IRBlock<'a, 'b, 'c> {
fn drop(&mut self) {
unsafe {
LLVMAppendExistingBasicBlock(self.function.value, self.blockref);
}
}
}

View File

@ -6,8 +6,8 @@ use llvm::{Error, IRBlock, IRContext, IRFunction, IRModule, IRValue};
use crate::{ use crate::{
ast::{ ast::{
BinaryOperator, Block, BlockLevelStatement, Expression, ExpressionKind, FunctionDefinition, Block, BlockLevelStatement, Expression, ExpressionKind, FunctionDefinition, LetStatement,
LetStatement, ReturnType, ReturnType,
}, },
TopLevelStatement, TopLevelStatement,
}; };
@ -42,19 +42,23 @@ impl FunctionDefinition {
fn codegen(&self, scope: &mut ScopeData, module: &mut IRModule) { fn codegen(&self, scope: &mut ScopeData, module: &mut IRModule) {
let FunctionDefinition(signature, block, _) = self; let FunctionDefinition(signature, block, _) = self;
let mut ir_function = IRFunction::new(&signature.name, module); let mut ir_function = IRFunction::new(&signature.name, module);
let ir_block = IRBlock::new(&mut ir_function);
block.codegen(scope.inner(ir_block)); let ir_block = IRBlock::new(&module);
let mut scope = scope.inner(ir_block);
block.codegen(&mut scope);
ir_function.attach(scope.block);
} }
} }
impl Block { impl Block {
fn codegen(&self, mut scope: Scope) { fn codegen(&self, scope: &mut Scope) {
for statement in &self.0 { for statement in &self.0 {
statement.codegen(&mut scope); statement.codegen(scope);
} }
if let Some((_, return_exp)) = &self.1 { if let Some((_, return_exp)) = &self.1 {
let value = return_exp.codegen(&mut scope); let value = return_exp.codegen(scope);
scope.block.add_return(Some(value)); scope.block.add_return(Some(value));
} }
} }
@ -83,7 +87,7 @@ impl Expression {
use ExpressionKind::*; use ExpressionKind::*;
match kind { match kind {
Literal(lit) => IRValue::from_literal(lit, &mut scope.block), Literal(lit) => IRValue::from_literal(lit, &mut scope.block.module),
VariableName(v) => scope.data.fetch(v), VariableName(v) => scope.data.fetch(v),
Binop(op, lhs, rhs) => { Binop(op, lhs, rhs) => {
let lhs = lhs.codegen(scope); let lhs = lhs.codegen(scope);
@ -112,11 +116,11 @@ impl ScopeData {
} }
} }
fn with_block<'a, 'b, 'c>(self, block: IRBlock<'a, 'b, 'c>) -> Scope<'a, 'b, 'c> { fn with_block<'a, 'b>(self, block: IRBlock<'a, 'b>) -> Scope<'a, 'b> {
Scope { data: self, block } Scope { data: self, block }
} }
fn inner<'a, 'b, 'c>(&self, block: IRBlock<'a, 'b, 'c>) -> Scope<'a, 'b, 'c> { fn inner<'a, 'b>(&self, block: IRBlock<'a, 'b>) -> Scope<'a, 'b> {
self.clone().with_block(block) self.clone().with_block(block)
} }
@ -135,13 +139,13 @@ impl ScopeData {
} }
} }
struct Scope<'a, 'b, 'c> { struct Scope<'a, 'b> {
data: ScopeData, data: ScopeData,
block: IRBlock<'a, 'b, 'c>, block: IRBlock<'a, 'b>,
} }
impl<'a, 'b, 'c> Scope<'a, 'b, 'c> { impl<'a, 'b> Scope<'a, 'b> {
fn inner(&self, block: IRBlock<'a, 'b, 'c>) -> Scope<'a, 'b, 'c> { fn inner(&self, block: IRBlock<'a, 'b>) -> Scope<'a, 'b> {
self.data.clone().with_block(block) self.data.clone().with_block(block)
} }
} }