Add Scope-struct
This commit is contained in:
parent
612b4d63a8
commit
817b7c2096
@ -1,4 +1,4 @@
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{hash_map, HashMap};
|
||||
|
||||
use crate::{
|
||||
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>) {
|
||||
let mut c = IRModule::new();
|
||||
for statement in statements {
|
||||
match statement {
|
||||
TopLevelStatement::FunctionDefinition(FunctionDefinition(sig, block)) => {
|
||||
let mut named_vars: HashMap<String, Value> = HashMap::new();
|
||||
|
||||
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 {
|
||||
match stmt {
|
||||
BlockLevelStatement::Let(let_statement) => {
|
||||
let value = codegen_exp(&mut c_block, &named_vars, let_statement.1);
|
||||
named_vars.insert(let_statement.0, value);
|
||||
let value = codegen_exp(&mut scope, let_statement.1);
|
||||
scope.set(let_statement.0, value).unwrap();
|
||||
}
|
||||
BlockLevelStatement::Return(_) => panic!("Should never exist!"),
|
||||
BlockLevelStatement::Import(_) => {}
|
||||
@ -31,35 +56,31 @@ pub fn codegen(statements: Vec<TopLevelStatement>) {
|
||||
}
|
||||
|
||||
let value = if let Some(exp) = block.1 {
|
||||
codegen_exp(&mut c_block, &named_vars, exp)
|
||||
codegen_exp(&mut scope, exp)
|
||||
} 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(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn codegen_exp(
|
||||
c_block: &mut IRBlock,
|
||||
named_vars: &HashMap<String, Value>,
|
||||
expression: Expression,
|
||||
) -> Value {
|
||||
fn codegen_exp(scope: &mut Scope, expression: Expression) -> Value {
|
||||
use Expression::*;
|
||||
match expression {
|
||||
Binop(op, lhs, rhs) => match op {
|
||||
BinaryOperator::Add => {
|
||||
let lhs = codegen_exp(c_block, named_vars, *lhs);
|
||||
let rhs = codegen_exp(c_block, named_vars, *rhs);
|
||||
c_block.add(lhs, rhs).unwrap()
|
||||
let lhs = codegen_exp(scope, *lhs);
|
||||
let rhs = codegen_exp(scope, *rhs);
|
||||
scope.block.add(lhs, rhs).unwrap()
|
||||
}
|
||||
BinaryOperator::Mult => panic!("Not implemented!"),
|
||||
},
|
||||
BlockExpr(_) => panic!("Not implemented!"),
|
||||
FunctionCall(_) => panic!("Not implemented!"),
|
||||
VariableName(name) => named_vars.get(&name).cloned().unwrap(),
|
||||
Literal(lit) => c_block.get_const(&lit),
|
||||
VariableName(name) => scope.get(&name).cloned().unwrap(),
|
||||
Literal(lit) => scope.block.get_const(&lit),
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user