Add Scope-struct

This commit is contained in:
Sofia 2023-08-02 18:29:20 +03:00
parent 612b4d63a8
commit 817b7c2096

View File

@ -1,4 +1,4 @@
use std::collections::HashMap; use std::collections::{hash_map, HashMap};
use crate::{ use crate::{
llvm_ir::{IRBlock, IRModule, Value, ValueType}, llvm_ir::{IRBlock, IRModule, Value, ValueType},
@ -8,21 +8,46 @@ use crate::{
}, },
}; };
pub struct Scope<'a> {
pub block: IRBlock<'a>,
named_vars: HashMap<String, Value>,
}
impl<'a> Scope<'a> {
pub fn from(block: IRBlock<'a>) -> Self {
Scope {
block,
named_vars: HashMap::new(),
}
}
pub fn get(&self, name: &String) -> Option<&Value> {
self.named_vars.get(name)
}
pub fn set(&mut self, name: String, val: Value) -> Result<(), ()> {
if let hash_map::Entry::Vacant(e) = self.named_vars.entry(name) {
e.insert(val);
Ok(())
} else {
Err(()) // TODO! Error Handling!
}
}
}
pub fn codegen(statements: Vec<TopLevelStatement>) { pub fn codegen(statements: Vec<TopLevelStatement>) {
let mut c = IRModule::new(); let mut c = IRModule::new();
for statement in statements { for statement in statements {
match statement { match statement {
TopLevelStatement::FunctionDefinition(FunctionDefinition(sig, block)) => { TopLevelStatement::FunctionDefinition(FunctionDefinition(sig, block)) => {
let mut named_vars: HashMap<String, Value> = HashMap::new();
let func = c.create_func(sig.name, ValueType::I32); let func = c.create_func(sig.name, ValueType::I32);
let mut c_block = c.create_block(); let mut scope = Scope::from(c.create_block());
for stmt in block.0 { for stmt in block.0 {
match stmt { match stmt {
BlockLevelStatement::Let(let_statement) => { BlockLevelStatement::Let(let_statement) => {
let value = codegen_exp(&mut c_block, &named_vars, let_statement.1); let value = codegen_exp(&mut scope, let_statement.1);
named_vars.insert(let_statement.0, value); scope.set(let_statement.0, value).unwrap();
} }
BlockLevelStatement::Return(_) => panic!("Should never exist!"), BlockLevelStatement::Return(_) => panic!("Should never exist!"),
BlockLevelStatement::Import(_) => {} BlockLevelStatement::Import(_) => {}
@ -31,35 +56,31 @@ pub fn codegen(statements: Vec<TopLevelStatement>) {
} }
let value = if let Some(exp) = block.1 { let value = if let Some(exp) = block.1 {
codegen_exp(&mut c_block, &named_vars, exp) codegen_exp(&mut scope, exp)
} else { } else {
c_block.get_const(&Literal::I32(0)) scope.block.get_const(&Literal::I32(0))
}; };
func.add_definition(value, c_block); func.add_definition(value, scope.block);
} }
TopLevelStatement::Import(_) => {} TopLevelStatement::Import(_) => {}
} }
} }
} }
fn codegen_exp( fn codegen_exp(scope: &mut Scope, expression: Expression) -> Value {
c_block: &mut IRBlock,
named_vars: &HashMap<String, Value>,
expression: Expression,
) -> Value {
use Expression::*; use Expression::*;
match expression { match expression {
Binop(op, lhs, rhs) => match op { Binop(op, lhs, rhs) => match op {
BinaryOperator::Add => { BinaryOperator::Add => {
let lhs = codegen_exp(c_block, named_vars, *lhs); let lhs = codegen_exp(scope, *lhs);
let rhs = codegen_exp(c_block, named_vars, *rhs); let rhs = codegen_exp(scope, *rhs);
c_block.add(lhs, rhs).unwrap() scope.block.add(lhs, rhs).unwrap()
} }
BinaryOperator::Mult => panic!("Not implemented!"), BinaryOperator::Mult => panic!("Not implemented!"),
}, },
BlockExpr(_) => panic!("Not implemented!"), BlockExpr(_) => panic!("Not implemented!"),
FunctionCall(_) => panic!("Not implemented!"), FunctionCall(_) => panic!("Not implemented!"),
VariableName(name) => named_vars.get(&name).cloned().unwrap(), VariableName(name) => scope.get(&name).cloned().unwrap(),
Literal(lit) => c_block.get_const(&lit), Literal(lit) => scope.block.get_const(&lit),
} }
} }