Split codegen properly

This commit is contained in:
Sofia 2023-08-02 18:37:31 +03:00
parent 817b7c2096
commit 9019e1e5a7
2 changed files with 48 additions and 36 deletions

View File

@ -25,8 +25,8 @@ impl<'a> Scope<'a> {
self.named_vars.get(name) self.named_vars.get(name)
} }
pub fn set(&mut self, name: String, val: Value) -> Result<(), ()> { pub fn set(&mut self, name: &String, val: Value) -> Result<(), ()> {
if let hash_map::Entry::Vacant(e) = self.named_vars.entry(name) { if let hash_map::Entry::Vacant(e) = self.named_vars.entry(name.clone()) {
e.insert(val); e.insert(val);
Ok(()) Ok(())
} else { } else {
@ -35,28 +35,19 @@ impl<'a> Scope<'a> {
} }
} }
pub fn codegen(statements: Vec<TopLevelStatement>) { impl TopLevelStatement {
let mut c = IRModule::new(); pub fn codegen(&self, module: &mut IRModule) {
for statement in statements { match self {
match statement {
TopLevelStatement::FunctionDefinition(FunctionDefinition(sig, block)) => { TopLevelStatement::FunctionDefinition(FunctionDefinition(sig, block)) => {
let func = c.create_func(sig.name, ValueType::I32); let func = module.create_func(&sig.name, ValueType::I32);
let mut scope = Scope::from(c.create_block()); let mut scope = Scope::from(module.create_block());
for stmt in block.0 { for statement in &block.0 {
match stmt { statement.codegen(&mut scope);
BlockLevelStatement::Let(let_statement) => {
let value = codegen_exp(&mut scope, let_statement.1);
scope.set(let_statement.0, value).unwrap();
}
BlockLevelStatement::Return(_) => panic!("Should never exist!"),
BlockLevelStatement::Import(_) => {}
BlockLevelStatement::Expression(_) => {}
}
} }
let value = if let Some(exp) = block.1 { let value = if let Some(exp) = &block.1 {
codegen_exp(&mut scope, exp) exp.codegen(&mut scope)
} else { } else {
scope.block.get_const(&Literal::I32(0)) scope.block.get_const(&Literal::I32(0))
}; };
@ -67,20 +58,36 @@ pub fn codegen(statements: Vec<TopLevelStatement>) {
} }
} }
fn codegen_exp(scope: &mut Scope, expression: Expression) -> Value { impl BlockLevelStatement {
use Expression::*; pub fn codegen(&self, scope: &mut Scope) {
match expression { match self {
Binop(op, lhs, rhs) => match op { BlockLevelStatement::Let(let_statement) => {
BinaryOperator::Add => { let val = let_statement.1.codegen(scope);
let lhs = codegen_exp(scope, *lhs); scope.set(&let_statement.0, val).unwrap();
let rhs = codegen_exp(scope, *rhs);
scope.block.add(lhs, rhs).unwrap()
} }
BinaryOperator::Mult => panic!("Not implemented!"), BlockLevelStatement::Return(_) => panic!("Should never exist!"),
}, BlockLevelStatement::Import(_) => {}
BlockExpr(_) => panic!("Not implemented!"), BlockLevelStatement::Expression(_) => {}
FunctionCall(_) => panic!("Not implemented!"), }
VariableName(name) => scope.get(&name).cloned().unwrap(), }
Literal(lit) => scope.block.get_const(&lit), }
impl Expression {
pub fn codegen(&self, scope: &mut Scope) -> Value {
use Expression::*;
match self {
Binop(op, lhs, rhs) => match op {
BinaryOperator::Add => {
let lhs = lhs.codegen(scope);
let rhs = rhs.codegen(scope);
scope.block.add(lhs, rhs).unwrap()
}
BinaryOperator::Mult => panic!("Not implemented!"),
},
BlockExpr(_) => panic!("Not implemented!"),
FunctionCall(_) => panic!("Not implemented!"),
VariableName(name) => scope.get(&name).cloned().unwrap(),
Literal(lit) => scope.block.get_const(&lit),
}
} }
} }

View File

@ -1,4 +1,6 @@
use crate::{lexer::Token, parser::TopLevelStatement, token_stream::TokenStream}; use crate::{
lexer::Token, llvm_ir::IRModule, parser::TopLevelStatement, token_stream::TokenStream,
};
pub static EASIEST: &str = include_str!("../reid/easiest.reid"); pub static EASIEST: &str = include_str!("../reid/easiest.reid");
pub static EASY: &str = include_str!("../reid/easy.reid"); pub static EASY: &str = include_str!("../reid/easy.reid");
@ -32,5 +34,8 @@ fn main() {
statements.push(statement); statements.push(statement);
} }
codegen::codegen(statements); let mut module = IRModule::new();
for statement in statements {
statement.codegen(&mut module);
}
} }