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