Add Scope
This commit is contained in:
parent
7208fe962e
commit
e00d9afc7b
@ -1,5 +1,10 @@
|
|||||||
// Arithmetic, function calls and imports!
|
// Arithmetic, function calls and imports!
|
||||||
|
|
||||||
fn main() {
|
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 {
|
pub enum IRType {
|
||||||
I32,
|
I32,
|
||||||
}
|
}
|
||||||
@ -86,7 +87,6 @@ impl IRType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use = "asd"]
|
|
||||||
pub struct IRFunction<'a, 'b> {
|
pub struct IRFunction<'a, 'b> {
|
||||||
module: &'b mut IRModule<'a>,
|
module: &'b mut IRModule<'a>,
|
||||||
/// The actual function
|
/// The actual function
|
||||||
@ -151,6 +151,7 @@ impl<'a, 'b, 'c> Drop for IRBlock<'a, 'b, 'c> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct IRValue {
|
pub struct IRValue {
|
||||||
pub ir_type: IRType,
|
pub ir_type: IRType,
|
||||||
ir_value: *mut LLVMValue,
|
ir_value: *mut LLVMValue,
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
mod llvm;
|
mod llvm;
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use llvm::{IRBlock, IRContext, IRFunction, IRModule, IRValue};
|
use llvm::{IRBlock, IRContext, IRFunction, IRModule, IRValue};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -19,49 +21,89 @@ pub fn from_statements(
|
|||||||
statements: Vec<TopLevelStatement>,
|
statements: Vec<TopLevelStatement>,
|
||||||
) -> Result<IRModule, Error> {
|
) -> Result<IRModule, Error> {
|
||||||
let mut module = context.module("testmod".to_owned());
|
let mut module = context.module("testmod".to_owned());
|
||||||
|
let mut scope = ScopeData::new();
|
||||||
for statement in statements {
|
for statement in statements {
|
||||||
statement.codegen(&mut module);
|
statement.codegen(&mut scope, &mut module);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(module)
|
Ok(module)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TopLevelStatement {
|
impl TopLevelStatement {
|
||||||
fn codegen(&self, module: &mut IRModule) {
|
fn codegen(&self, scope: &mut ScopeData, module: &mut IRModule) {
|
||||||
match self {
|
match self {
|
||||||
Self::FunctionDefinition(func) => func.codegen(module),
|
Self::FunctionDefinition(func) => func.codegen(scope, module),
|
||||||
Self::Import(_) => panic!("not implemented"),
|
Self::Import(_) => panic!("not implemented"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FunctionDefinition {
|
impl FunctionDefinition {
|
||||||
fn codegen(&self, module: &mut IRModule) {
|
fn codegen(&self, scope: &mut ScopeData, module: &mut IRModule) {
|
||||||
let FunctionDefinition(signature, block, _) = self;
|
let FunctionDefinition(signature, block, _) = self;
|
||||||
let mut function = IRFunction::new(&signature.name, module);
|
let mut ir_function = IRFunction::new(&signature.name, module);
|
||||||
block.codegen(&mut function)
|
let ir_block = IRBlock::new(&mut ir_function);
|
||||||
|
block.codegen(scope.with_block(ir_block));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Block {
|
impl Block {
|
||||||
fn codegen(&self, function: &mut IRFunction) {
|
fn codegen(&self, mut scope: Scope) {
|
||||||
let mut block = IRBlock::new(function);
|
|
||||||
|
|
||||||
if let Some((_, return_exp)) = &self.1 {
|
if let Some((_, return_exp)) = &self.1 {
|
||||||
let value = return_exp.codegen(&mut block);
|
let value = return_exp.codegen(&mut scope);
|
||||||
block.add_return(Some(value))
|
scope.block.add_return(Some(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Expression {
|
impl Expression {
|
||||||
fn codegen(&self, block: &mut IRBlock) -> IRValue {
|
fn codegen(&self, scope: &mut Scope) -> IRValue {
|
||||||
let Expression(kind, _) = self;
|
let Expression(kind, _) = self;
|
||||||
|
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
match kind {
|
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"),
|
_ => 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