From 2ced45eb404a5d0bb0333c4285c89f85afcf2a62 Mon Sep 17 00:00:00 2001 From: sofia Date: Wed, 2 Aug 2023 18:43:47 +0300 Subject: [PATCH] Refactor --- src/{parser.rs => ast.rs} | 0 src/codegen.rs | 16 +++++++-------- src/llvm_ir.rs | 41 ++++++++++++++++++++++++--------------- src/main.rs | 9 ++++----- src/token_stream.rs | 2 +- 5 files changed, 38 insertions(+), 30 deletions(-) rename src/{parser.rs => ast.rs} (100%) diff --git a/src/parser.rs b/src/ast.rs similarity index 100% rename from src/parser.rs rename to src/ast.rs diff --git a/src/codegen.rs b/src/codegen.rs index 56ed13c..238eea1 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -1,16 +1,16 @@ use std::collections::{hash_map, HashMap}; use crate::{ - llvm_ir::{IRBlock, IRModule, Value, ValueType}, - parser::{ + ast::{ BinaryOperator, BlockLevelStatement, Expression, FunctionDefinition, Literal, TopLevelStatement, }, + llvm_ir::{IRBlock, IRModule, IRValue, IRValueType}, }; pub struct Scope<'a> { pub block: IRBlock<'a>, - named_vars: HashMap, + named_vars: HashMap, } impl<'a> Scope<'a> { @@ -21,11 +21,11 @@ impl<'a> Scope<'a> { } } - pub fn get(&self, name: &String) -> Option<&Value> { + pub fn get(&self, name: &String) -> Option<&IRValue> { self.named_vars.get(name) } - pub fn set(&mut self, name: &str, val: Value) -> Result<(), ()> { + pub fn set(&mut self, name: &str, val: IRValue) -> Result<(), ()> { if let hash_map::Entry::Vacant(e) = self.named_vars.entry(name.to_owned()) { e.insert(val); Ok(()) @@ -39,7 +39,7 @@ impl TopLevelStatement { pub fn codegen(&self, module: &mut IRModule) { match self { TopLevelStatement::FunctionDefinition(FunctionDefinition(sig, block)) => { - let func = module.create_func(&sig.name, ValueType::I32); + let func = module.create_func(&sig.name, IRValueType::I32); let mut scope = Scope::from(module.create_block()); for statement in &block.0 { @@ -49,7 +49,7 @@ impl TopLevelStatement { let value = if let Some(exp) = &block.1 { exp.codegen(&mut scope) } else { - scope.block.get_const(&Literal::I32(0)) + panic!("Void-return type function not yet implemented!"); }; func.add_definition(value, scope.block); } @@ -73,7 +73,7 @@ impl BlockLevelStatement { } impl Expression { - pub fn codegen(&self, scope: &mut Scope) -> Value { + pub fn codegen(&self, scope: &mut Scope) -> IRValue { use Expression::*; match self { Binop(op, lhs, rhs) => match op { diff --git a/src/llvm_ir.rs b/src/llvm_ir.rs index c23b3fe..b971d37 100644 --- a/src/llvm_ir.rs +++ b/src/llvm_ir.rs @@ -3,7 +3,7 @@ use std::mem; use llvm_sys::{core::*, prelude::*, LLVMBuilder, LLVMContext, LLVMModule}; -use crate::parser::Literal; +use crate::ast::Literal; macro_rules! cstr { ($string:expr) => { @@ -12,11 +12,11 @@ macro_rules! cstr { } #[derive(Clone, Debug, PartialEq, Eq)] -pub enum ValueType { +pub enum IRValueType { I32, } -impl ValueType { +impl IRValueType { unsafe fn get_llvm_type(&self, codegen: &mut IRModule) -> LLVMTypeRef { match *self { Self::I32 => LLVMInt32TypeInContext(codegen.context), @@ -26,7 +26,7 @@ impl ValueType { #[derive(Clone, Debug)] #[must_use = "value contains raw pointer and must be inserted somewhere"] -pub struct Value(ValueType, LLVMValueRef); +pub struct IRValue(IRValueType, LLVMValueRef); fn into_cstring>(value: T) -> CString { let string = value.into(); @@ -40,11 +40,11 @@ pub struct IRModule { } impl IRModule { - pub fn new() -> IRModule { + pub fn new>(name: T) -> IRModule { unsafe { // Set up a context, module and builder in that context. let context = LLVMContextCreate(); - let module = LLVMModuleCreateWithNameInContext(cstr!("testmodule"), context); + let module = LLVMModuleCreateWithNameInContext(into_cstring(name).as_ptr(), context); let builder = LLVMCreateBuilderInContext(context); IRModule { @@ -59,7 +59,11 @@ impl IRModule { IRBlock::create("entry", self) } - pub fn create_func>(&mut self, name: T, return_type: ValueType) -> IRFunction { + pub fn create_func>( + &mut self, + name: T, + return_type: IRValueType, + ) -> IRFunction { unsafe { let mut argts = []; let func_type = LLVMFunctionType( @@ -71,10 +75,16 @@ impl IRModule { let anon_func = LLVMAddFunction(self.module, into_cstring(name).as_ptr(), func_type); IRFunction { - value: Value(return_type, anon_func), + value: IRValue(return_type, anon_func), } } } + + pub fn dump(&mut self) { + unsafe { + LLVMDumpModule(self.module); + } + } } impl Drop for IRModule { @@ -82,7 +92,6 @@ impl Drop for IRModule { // Clean up. Values created in the context mostly get cleaned up there. unsafe { LLVMDisposeBuilder(self.builder); - LLVMDumpModule(self.module); LLVMDisposeModule(self.module); LLVMContextDispose(self.context); } @@ -90,11 +99,11 @@ impl Drop for IRModule { } pub struct IRFunction { - value: Value, + value: IRValue, } impl IRFunction { - pub fn add_definition(self, ret: Value, block: IRBlock) { + pub fn add_definition(self, ret: IRValue, block: IRBlock) { unsafe { LLVMAppendExistingBasicBlock(self.value.1, block.blockref); LLVMBuildRet(block.module.builder, ret.1); @@ -120,11 +129,11 @@ impl<'a> IRBlock<'a> { } } - pub fn get_const(&mut self, literal_type: &Literal) -> Value { + pub fn get_const(&mut self, literal_type: &Literal) -> IRValue { unsafe { match *literal_type { - Literal::I32(v) => Value( - ValueType::I32, + Literal::I32(v) => IRValue( + IRValueType::I32, LLVMConstInt( LLVMInt32TypeInContext(self.module.context), mem::transmute(v as i64), @@ -135,10 +144,10 @@ impl<'a> IRBlock<'a> { } } - pub fn add(&mut self, lhs: Value, rhs: Value) -> Result { + pub fn add(&mut self, lhs: IRValue, rhs: IRValue) -> Result { unsafe { if lhs.0 == rhs.0 { - Ok(Value( + Ok(IRValue( lhs.0, LLVMBuildAdd(self.module.builder, lhs.1, rhs.1, cstr!("tmpadd")), )) diff --git a/src/main.rs b/src/main.rs index 9ac3cb1..38b3a6c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,14 @@ -use crate::{ - lexer::Token, llvm_ir::IRModule, parser::TopLevelStatement, token_stream::TokenStream, -}; +use crate::{ast::TopLevelStatement, lexer::Token, llvm_ir::IRModule, token_stream::TokenStream}; pub static EASIEST: &str = include_str!("../reid/easiest.reid"); pub static EASY: &str = include_str!("../reid/easy.reid"); pub static MEDIUM: &str = include_str!("../reid/medium.reid"); pub static HARD: &str = include_str!("../reid/hard.reid"); +mod ast; mod codegen; mod lexer; mod llvm_ir; -mod parser; mod token_stream; // TODO: @@ -34,8 +32,9 @@ fn main() { statements.push(statement); } - let mut module = IRModule::new(); + let mut module = IRModule::new("testmod"); for statement in statements { statement.codegen(&mut module); } + module.dump(); } diff --git a/src/token_stream.rs b/src/token_stream.rs index 4966b24..e583741 100644 --- a/src/token_stream.rs +++ b/src/token_stream.rs @@ -1,6 +1,6 @@ use crate::{ + ast::Parse, lexer::{FullToken, Token}, - parser::Parse, }; pub struct TokenStream<'a, 'b> {