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!
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 {
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,

View File

@ -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<TopLevelStatement>,
) -> Result<IRModule, Error> {
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<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>,
}