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