From e00d9afc7b7459d0421d3ff40a299f1c08b201f4 Mon Sep 17 00:00:00 2001 From: sofia Date: Wed, 21 Aug 2024 23:07:04 +0300 Subject: [PATCH] Add Scope --- examples/reid/easy.reid | 7 ++++- src/codegen/llvm.rs | 3 +- src/codegen/mod.rs | 68 +++++++++++++++++++++++++++++++++-------- 3 files changed, 63 insertions(+), 15 deletions(-) diff --git a/examples/reid/easy.reid b/examples/reid/easy.reid index 2dc010c..87362f3 100644 --- a/examples/reid/easy.reid +++ b/examples/reid/easy.reid @@ -1,5 +1,10 @@ // Arithmetic, function calls and imports! fn main() { - return 5; + let test = 9; + let simpleAdd = 2 + 2; + let simpleMult = 7 * 2; + let arithmetic = 3 + 2 * 5 + 1 * 2; + + return arithmetic + simpleMult * arithmetic; } \ No newline at end of file diff --git a/src/codegen/llvm.rs b/src/codegen/llvm.rs index 04dd0c8..1252e13 100644 --- a/src/codegen/llvm.rs +++ b/src/codegen/llvm.rs @@ -71,6 +71,7 @@ impl<'a> Drop for IRModule<'a> { } } +#[derive(Clone)] pub enum IRType { I32, } @@ -86,7 +87,6 @@ impl IRType { } } -#[must_use = "asd"] pub struct IRFunction<'a, 'b> { module: &'b mut IRModule<'a>, /// The actual function @@ -151,6 +151,7 @@ impl<'a, 'b, 'c> Drop for IRBlock<'a, 'b, 'c> { } } +#[derive(Clone)] pub struct IRValue { pub ir_type: IRType, ir_value: *mut LLVMValue, diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index c47a190..51ab6ef 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1,5 +1,7 @@ mod llvm; +use std::collections::HashMap; + use llvm::{IRBlock, IRContext, IRFunction, IRModule, IRValue}; use crate::{ @@ -19,49 +21,89 @@ pub fn from_statements( statements: Vec, ) -> Result { let mut module = context.module("testmod".to_owned()); + let mut scope = ScopeData::new(); for statement in statements { - statement.codegen(&mut module); + statement.codegen(&mut scope, &mut module); } Ok(module) } impl TopLevelStatement { - fn codegen(&self, module: &mut IRModule) { + fn codegen(&self, scope: &mut ScopeData, module: &mut IRModule) { match self { - Self::FunctionDefinition(func) => func.codegen(module), + Self::FunctionDefinition(func) => func.codegen(scope, module), Self::Import(_) => panic!("not implemented"), } } } impl FunctionDefinition { - fn codegen(&self, module: &mut IRModule) { + fn codegen(&self, scope: &mut ScopeData, module: &mut IRModule) { let FunctionDefinition(signature, block, _) = self; - let mut function = IRFunction::new(&signature.name, module); - block.codegen(&mut function) + let mut ir_function = IRFunction::new(&signature.name, module); + let ir_block = IRBlock::new(&mut ir_function); + block.codegen(scope.with_block(ir_block)); } } impl Block { - fn codegen(&self, function: &mut IRFunction) { - let mut block = IRBlock::new(function); - + fn codegen(&self, mut scope: Scope) { if let Some((_, return_exp)) = &self.1 { - let value = return_exp.codegen(&mut block); - block.add_return(Some(value)) + let value = return_exp.codegen(&mut scope); + scope.block.add_return(Some(value)); } } } impl Expression { - fn codegen(&self, block: &mut IRBlock) -> IRValue { + fn codegen(&self, scope: &mut Scope) -> IRValue { let Expression(kind, _) = self; use ExpressionKind::*; match kind { - Literal(lit) => IRValue::from_literal(lit, block), + Literal(lit) => IRValue::from_literal(lit, &mut scope.block), + VariableName(v) => scope.data.fetch(v), _ => panic!("expression type not supported"), } } } + +#[derive(Clone)] +struct ScopeData { + vars: HashMap, +} + +impl ScopeData { + fn new() -> ScopeData { + ScopeData { + vars: HashMap::new(), + } + } + + fn with_block<'a, 'b, 'c>(&self, block: IRBlock<'a, 'b, 'c>) -> Scope<'a, 'b, 'c> { + Scope { + data: self.clone(), + block, + } + } + + fn fetch(&self, name: &String) -> IRValue { + match self.vars.get(name) { + Some(val) => val.clone(), + _ => panic!("No such variable in scope: {}", name), + } + } + + fn insert(&mut self, name: &String, value: IRValue) { + match self.vars.insert(name.clone(), value) { + Some(_) => panic!("{} was already defined in scope", name), + _ => {} + } + } +} + +struct Scope<'a, 'b, 'c> { + data: ScopeData, + block: IRBlock<'a, 'b, 'c>, +}