Make macros generate globals
This commit is contained in:
		
							parent
							
								
									50a875ad21
								
							
						
					
					
						commit
						735c3231b1
					
				| @ -128,6 +128,7 @@ impl ast::Module { | ||||
|             imports, | ||||
|             associated_functions, | ||||
|             functions, | ||||
|             globals: Vec::new(), | ||||
|             path: self.path.clone(), | ||||
|             is_main: self.is_main, | ||||
|             tokens: self.tokens, | ||||
|  | ||||
| @ -3,6 +3,7 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc}; | ||||
| use allocator::{Allocator, AllocatorScope}; | ||||
| use intrinsics::*; | ||||
| use reid_lib::{ | ||||
|     builder::ConstantValue, | ||||
|     compile::CompiledModule, | ||||
|     debug_information::{ | ||||
|         DebugFileData, DebugLexicalScope, DebugLocalVariable, DebugLocation, DebugMetadata, DebugRecordKind, | ||||
| @ -96,6 +97,14 @@ impl Default for State { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl mir::GlobalKind { | ||||
|     fn codegen<'ctx>(&'ctx self, context: &'ctx Context, module: &Module) -> Result<ConstantValue, ErrorKind> { | ||||
|         Ok(match self { | ||||
|             mir::GlobalKind::Literal(literal) => module.add_constant(literal.as_const_kind()), | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl mir::Module { | ||||
|     fn codegen<'ctx>( | ||||
|         &'ctx self, | ||||
| @ -105,8 +114,10 @@ impl mir::Module { | ||||
|         let mut module = context.module(&self.name, self.is_main); | ||||
|         let tokens = &self.tokens; | ||||
| 
 | ||||
|         let const_value = module.add_constant(ConstValueKind::I128(132)); | ||||
|         module.add_global("some_global", const_value); | ||||
|         for global in &self.globals { | ||||
|             let const_value = global.kind.codegen(context, &module)?; | ||||
|             module.add_global(&global.name, const_value); | ||||
|         } | ||||
| 
 | ||||
|         let (debug, compile_unit) = if let Some(path) = &self.path { | ||||
|             module.create_debug_info(DebugFileData { | ||||
|  | ||||
| @ -34,11 +34,13 @@ impl mir::CmpOperator { | ||||
| 
 | ||||
| impl mir::Literal { | ||||
|     pub(super) fn as_const(&self, block: &mut Block) -> InstructionValue { | ||||
|         block.build_named(format!("{}", self), self.as_const_kind()).unwrap() | ||||
|         block | ||||
|             .build_named(format!("{}", self), Instr::Constant(self.as_const_kind())) | ||||
|             .unwrap() | ||||
|     } | ||||
| 
 | ||||
|     pub(super) fn as_const_kind(&self) -> Instr { | ||||
|         Instr::Constant(match self.clone() { | ||||
|     pub(super) fn as_const_kind(&self) -> ConstValueKind { | ||||
|         match self.clone() { | ||||
|             mir::Literal::I8(val) => ConstValueKind::I8(val), | ||||
|             mir::Literal::I16(val) => ConstValueKind::I16(val), | ||||
|             mir::Literal::I32(val) => ConstValueKind::I32(val), | ||||
| @ -61,7 +63,7 @@ impl mir::Literal { | ||||
|             mir::Literal::F128(val) => ConstValueKind::F128(val), | ||||
|             mir::Literal::F128PPC(val) => ConstValueKind::F128PPC(val), | ||||
|             mir::Literal::Char(c) => ConstValueKind::U8(c as u8), | ||||
|         }) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,11 +1,11 @@ | ||||
| use std::collections::HashMap; | ||||
| 
 | ||||
| use crate::mir::{self, FunctionCall, IfExpression, WhileStatement}; | ||||
| use crate::mir::{self, FunctionCall, GlobalKind, GlobalValue, IfExpression, Literal, WhileStatement}; | ||||
| 
 | ||||
| use super::pass::{Pass, PassResult, PassState}; | ||||
| 
 | ||||
| pub trait MacroFunction: std::fmt::Debug { | ||||
|     fn generate<'ctx, 'a>(&self, params: &[mir::Literal]) -> Result<mir::ExprKind, ErrorKind>; | ||||
|     fn generate<'ctx, 'a>(&self, params: &[mir::Literal]) -> Result<(Vec<GlobalValue>, mir::ExprKind), ErrorKind>; | ||||
| } | ||||
| 
 | ||||
| #[derive(thiserror::Error, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] | ||||
| @ -36,52 +36,57 @@ impl Pass for MacroPass { | ||||
| 
 | ||||
|     fn module(&mut self, module: &mut mir::Module, mut state: PassState<Self::Data, Self::TError>) -> PassResult { | ||||
|         for function in &mut module.functions { | ||||
|             match &mut function.kind { | ||||
|                 mir::FunctionDefinitionKind::Local(block, _) => block.gen_macros(self, &mut state)?, | ||||
|                 _ => {} | ||||
|             let globals = match &mut function.kind { | ||||
|                 mir::FunctionDefinitionKind::Local(block, _) => block.gen_macros(self, &mut state), | ||||
|                 _ => Vec::new(), | ||||
|             }; | ||||
| 
 | ||||
|             module.globals.extend(globals); | ||||
|         } | ||||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl mir::Block { | ||||
|     fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState) -> PassResult { | ||||
|     fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState) -> Vec<GlobalValue> { | ||||
|         let mut globals = Vec::new(); | ||||
|         for statement in &mut self.statements { | ||||
|             statement.gen_macros(data, state)?; | ||||
|             globals.extend(statement.gen_macros(data, state)); | ||||
|         } | ||||
|         if let Some((_, Some(return_expr))) = &mut self.return_expression { | ||||
|             return_expr.gen_macros(data, state)?; | ||||
|             globals.extend(return_expr.gen_macros(data, state)); | ||||
|         } | ||||
|         Ok(()) | ||||
|         globals | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl mir::Statement { | ||||
|     fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState) -> PassResult { | ||||
|     fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState) -> Vec<GlobalValue> { | ||||
|         let mut globals = Vec::new(); | ||||
|         match &mut self.0 { | ||||
|             mir::StmtKind::Let(.., expr) => { | ||||
|                 expr.gen_macros(data, state)?; | ||||
|                 globals.extend(expr.gen_macros(data, state)); | ||||
|             } | ||||
|             mir::StmtKind::Set(lhs, rhs) => { | ||||
|                 lhs.gen_macros(data, state)?; | ||||
|                 rhs.gen_macros(data, state)?; | ||||
|                 globals.extend(lhs.gen_macros(data, state)); | ||||
|                 globals.extend(rhs.gen_macros(data, state)); | ||||
|             } | ||||
|             mir::StmtKind::Import(_) => {} | ||||
|             mir::StmtKind::Expression(expr) => { | ||||
|                 expr.gen_macros(data, state)?; | ||||
|                 globals.extend(expr.gen_macros(data, state)); | ||||
|             } | ||||
|             mir::StmtKind::While(WhileStatement { condition, block, .. }) => { | ||||
|                 condition.gen_macros(data, state)?; | ||||
|                 block.gen_macros(data, state)?; | ||||
|                 globals.extend(condition.gen_macros(data, state)); | ||||
|                 globals.extend(block.gen_macros(data, state)); | ||||
|             } | ||||
|         }; | ||||
|         Ok(()) | ||||
|         globals | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl mir::Expression { | ||||
|     fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState) -> PassResult { | ||||
|     fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState) -> Vec<GlobalValue> { | ||||
|         let mut globals = Vec::new(); | ||||
|         match &mut self.0 { | ||||
|             mir::ExprKind::FunctionCall(function_call) => { | ||||
|                 if function_call.is_macro { | ||||
| @ -93,13 +98,15 @@ impl mir::Expression { | ||||
|                                 _ => state.note_errors(&vec![ErrorKind::InvalidMacroArgs], param.1), | ||||
|                             } | ||||
|                         } | ||||
|                         *self = state.or_else( | ||||
|                         let (generated_globals, expr) = state.or_else( | ||||
|                             existing_macro | ||||
|                                 .generate(&literals) | ||||
|                                 .map(|kind| mir::Expression(kind, self.1)), | ||||
|                             self.clone(), | ||||
|                                 .map(|(globals, kind)| (globals, mir::Expression(kind, self.1))), | ||||
|                             (Vec::new(), self.clone()), | ||||
|                             self.1, | ||||
|                         ); | ||||
|                         globals.extend(generated_globals); | ||||
|                         *self = expr; | ||||
|                     } else { | ||||
|                         state.note_errors( | ||||
|                             &vec![ErrorKind::NoSuchMacro(function_call.name.clone())], | ||||
| @ -110,26 +117,26 @@ impl mir::Expression { | ||||
|             } | ||||
|             mir::ExprKind::Variable(_) => {} | ||||
|             mir::ExprKind::Indexed(expression, _, expression1) => { | ||||
|                 expression.gen_macros(data, state)?; | ||||
|                 expression1.gen_macros(data, state)?; | ||||
|                 globals.extend(expression.gen_macros(data, state)); | ||||
|                 globals.extend(expression1.gen_macros(data, state)); | ||||
|             } | ||||
|             mir::ExprKind::Accessed(expression, ..) => { | ||||
|                 expression.gen_macros(data, state)?; | ||||
|                 globals.extend(expression.gen_macros(data, state)); | ||||
|             } | ||||
|             mir::ExprKind::Array(expressions) => { | ||||
|                 for expression in expressions { | ||||
|                     expression.gen_macros(data, state)?; | ||||
|                     globals.extend(expression.gen_macros(data, state)); | ||||
|                 } | ||||
|             } | ||||
|             mir::ExprKind::Struct(_, items) => { | ||||
|                 for item in items { | ||||
|                     item.1.gen_macros(data, state)?; | ||||
|                     globals.extend(item.1.gen_macros(data, state)); | ||||
|                 } | ||||
|             } | ||||
|             mir::ExprKind::Literal(_) => {} | ||||
|             mir::ExprKind::BinOp(_, expression, expression1, _) => { | ||||
|                 expression.gen_macros(data, state)?; | ||||
|                 expression1.gen_macros(data, state)?; | ||||
|                 globals.extend(expression.gen_macros(data, state)); | ||||
|                 globals.extend(expression1.gen_macros(data, state)); | ||||
|             } | ||||
|             mir::ExprKind::AssociatedFunctionCall( | ||||
|                 _, | ||||
| @ -138,30 +145,30 @@ impl mir::Expression { | ||||
|                 }, | ||||
|             ) => { | ||||
|                 for expression in parameters { | ||||
|                     expression.gen_macros(data, state)?; | ||||
|                     globals.extend(expression.gen_macros(data, state)); | ||||
|                 } | ||||
|             } | ||||
|             mir::ExprKind::If(IfExpression(cond, lhs, rhs)) => { | ||||
|                 cond.gen_macros(data, state)?; | ||||
|                 lhs.gen_macros(data, state)?; | ||||
|                 globals.extend(cond.gen_macros(data, state)); | ||||
|                 globals.extend(lhs.gen_macros(data, state)); | ||||
|                 if let Some(rhs) = rhs.as_mut() { | ||||
|                     rhs.gen_macros(data, state)?; | ||||
|                     globals.extend(rhs.gen_macros(data, state)); | ||||
|                 } | ||||
|             } | ||||
|             mir::ExprKind::Block(block) => { | ||||
|                 block.gen_macros(data, state)?; | ||||
|                 globals.extend(block.gen_macros(data, state)); | ||||
|             } | ||||
|             mir::ExprKind::Borrow(expression, _) => { | ||||
|                 expression.gen_macros(data, state)?; | ||||
|                 globals.extend(expression.gen_macros(data, state)); | ||||
|             } | ||||
|             mir::ExprKind::Deref(expression) => { | ||||
|                 expression.gen_macros(data, state)?; | ||||
|                 globals.extend(expression.gen_macros(data, state)); | ||||
|             } | ||||
|             mir::ExprKind::CastTo(expression, _) => { | ||||
|                 expression.gen_macros(data, state)?; | ||||
|                 globals.extend(expression.gen_macros(data, state)); | ||||
|             } | ||||
|         } | ||||
|         Ok(()) | ||||
|         globals | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -176,9 +183,13 @@ pub fn form_macros() -> HashMap<String, Box<dyn MacroFunction>> { | ||||
| #[derive(Debug)] | ||||
| pub struct TestMacro; | ||||
| impl MacroFunction for TestMacro { | ||||
|     fn generate<'ctx, 'a>(&self, _: &[mir::Literal]) -> Result<mir::ExprKind, ErrorKind> { | ||||
|         Ok(mir::ExprKind::Literal(mir::Literal::Vague(mir::VagueLiteral::Number( | ||||
|             5, | ||||
|         )))) | ||||
|     fn generate<'ctx, 'a>(&self, _: &[mir::Literal]) -> Result<(Vec<GlobalValue>, mir::ExprKind), ErrorKind> { | ||||
|         Ok(( | ||||
|             vec![GlobalValue { | ||||
|                 name: "sometestglobalvalue".to_owned(), | ||||
|                 kind: GlobalKind::Literal(Literal::I16(12)), | ||||
|             }], | ||||
|             mir::ExprKind::Literal(mir::Literal::Vague(mir::VagueLiteral::Number(5))), | ||||
|         )) | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -421,11 +421,23 @@ pub struct Module { | ||||
|     pub functions: Vec<FunctionDefinition>, | ||||
|     pub typedefs: Vec<TypeDefinition>, | ||||
|     pub binop_defs: Vec<BinopDefinition>, | ||||
|     pub globals: Vec<GlobalValue>, | ||||
|     pub path: Option<PathBuf>, | ||||
|     pub tokens: Vec<FullToken>, | ||||
|     pub is_main: bool, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct GlobalValue { | ||||
|     pub name: String, | ||||
|     pub kind: GlobalKind, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub enum GlobalKind { | ||||
|     Literal(Literal), | ||||
| } | ||||
| 
 | ||||
| pub type ModuleMap = HashMap<SourceModuleId, Module>; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user