Add Scope
This commit is contained in:
parent
7208fe962e
commit
e00d9afc7b
@ -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;
|
||||
}
|
@ -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,
|
||||
|
@ -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>,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user