Add Scope

This commit is contained in:
Sofia 2024-08-21 23:07:04 +03:00
parent 7208fe962e
commit e00d9afc7b
3 changed files with 63 additions and 15 deletions

View File

@ -1,5 +1,10 @@
// Arithmetic, function calls and imports! // Arithmetic, function calls and imports!
fn main() { 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;
} }

View File

@ -71,6 +71,7 @@ impl<'a> Drop for IRModule<'a> {
} }
} }
#[derive(Clone)]
pub enum IRType { pub enum IRType {
I32, I32,
} }
@ -86,7 +87,6 @@ impl IRType {
} }
} }
#[must_use = "asd"]
pub struct IRFunction<'a, 'b> { pub struct IRFunction<'a, 'b> {
module: &'b mut IRModule<'a>, module: &'b mut IRModule<'a>,
/// The actual function /// The actual function
@ -151,6 +151,7 @@ impl<'a, 'b, 'c> Drop for IRBlock<'a, 'b, 'c> {
} }
} }
#[derive(Clone)]
pub struct IRValue { pub struct IRValue {
pub ir_type: IRType, pub ir_type: IRType,
ir_value: *mut LLVMValue, ir_value: *mut LLVMValue,

View File

@ -1,5 +1,7 @@
mod llvm; mod llvm;
use std::collections::HashMap;
use llvm::{IRBlock, IRContext, IRFunction, IRModule, IRValue}; use llvm::{IRBlock, IRContext, IRFunction, IRModule, IRValue};
use crate::{ use crate::{
@ -19,49 +21,89 @@ pub fn from_statements(
statements: Vec<TopLevelStatement>, statements: Vec<TopLevelStatement>,
) -> Result<IRModule, Error> { ) -> Result<IRModule, Error> {
let mut module = context.module("testmod".to_owned()); let mut module = context.module("testmod".to_owned());
let mut scope = ScopeData::new();
for statement in statements { for statement in statements {
statement.codegen(&mut module); statement.codegen(&mut scope, &mut module);
} }
Ok(module) Ok(module)
} }
impl TopLevelStatement { impl TopLevelStatement {
fn codegen(&self, module: &mut IRModule) { fn codegen(&self, scope: &mut ScopeData, module: &mut IRModule) {
match self { match self {
Self::FunctionDefinition(func) => func.codegen(module), Self::FunctionDefinition(func) => func.codegen(scope, module),
Self::Import(_) => panic!("not implemented"), Self::Import(_) => panic!("not implemented"),
} }
} }
} }
impl FunctionDefinition { impl FunctionDefinition {
fn codegen(&self, module: &mut IRModule) { fn codegen(&self, scope: &mut ScopeData, module: &mut IRModule) {
let FunctionDefinition(signature, block, _) = self; let FunctionDefinition(signature, block, _) = self;
let mut function = IRFunction::new(&signature.name, module); let mut ir_function = IRFunction::new(&signature.name, module);
block.codegen(&mut function) let ir_block = IRBlock::new(&mut ir_function);
block.codegen(scope.with_block(ir_block));
} }
} }
impl Block { impl Block {
fn codegen(&self, function: &mut IRFunction) { fn codegen(&self, mut scope: Scope) {
let mut block = IRBlock::new(function);
if let Some((_, return_exp)) = &self.1 { if let Some((_, return_exp)) = &self.1 {
let value = return_exp.codegen(&mut block); let value = return_exp.codegen(&mut scope);
block.add_return(Some(value)) scope.block.add_return(Some(value));
} }
} }
} }
impl Expression { impl Expression {
fn codegen(&self, block: &mut IRBlock) -> IRValue { fn codegen(&self, scope: &mut Scope) -> IRValue {
let Expression(kind, _) = self; let Expression(kind, _) = self;
use ExpressionKind::*; use ExpressionKind::*;
match kind { 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"), _ => panic!("expression type not supported"),
} }
} }
} }
#[derive(Clone)]
struct ScopeData {
vars: HashMap<String, IRValue>,
}
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>,
}