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