Add module_id for modules and metadata
This commit is contained in:
		
							parent
							
								
									e2dc1a3f85
								
							
						
					
					
						commit
						64e34ecf13
					
				| @ -161,6 +161,7 @@ fn main() { | ||||
|     let mir_context = mir::Context { | ||||
|         modules: vec![Module { | ||||
|             name: "test module".to_owned(), | ||||
|             module_id: SourceModuleId::default(), | ||||
|             imports: vec![], | ||||
|             functions: vec![fibonacci, main], | ||||
|             typedefs: Vec::new(), | ||||
|  | ||||
| @ -2,7 +2,7 @@ use std::path::PathBuf; | ||||
| 
 | ||||
| use crate::{ | ||||
|     ast::{self}, | ||||
|     mir::{self, NamedVariableRef, StmtKind, StructField, StructType}, | ||||
|     mir::{self, NamedVariableRef, SourceModuleId, StmtKind, StructField, StructType}, | ||||
| }; | ||||
| 
 | ||||
| impl mir::Context { | ||||
| @ -12,7 +12,7 @@ impl mir::Context { | ||||
| } | ||||
| 
 | ||||
| impl ast::Module { | ||||
|     pub fn process(&self) -> mir::Module { | ||||
|     pub fn process(&self, module_id: SourceModuleId) -> mir::Module { | ||||
|         let mut imports = Vec::new(); | ||||
|         let mut functions = Vec::new(); | ||||
|         let mut typedefs = Vec::new(); | ||||
| @ -21,7 +21,7 @@ impl ast::Module { | ||||
|         for stmt in &self.top_level_statements { | ||||
|             match stmt { | ||||
|                 Import(import) => { | ||||
|                     imports.push(mir::Import(import.0.clone(), import.1.into())); | ||||
|                     imports.push(mir::Import(import.0.clone(), import.1.as_meta(module_id))); | ||||
|                 } | ||||
|                 FunctionDefinition(ast::FunctionDefinition(signature, is_pub, block, range)) => { | ||||
|                     let def = mir::FunctionDefinition { | ||||
| @ -39,7 +39,10 @@ impl ast::Module { | ||||
|                             .cloned() | ||||
|                             .map(|p| (p.0, p.1.into())) | ||||
|                             .collect(), | ||||
|                         kind: mir::FunctionDefinitionKind::Local(block.into_mir(), (*range).into()), | ||||
|                         kind: mir::FunctionDefinitionKind::Local( | ||||
|                             block.into_mir(module_id), | ||||
|                             (*range).as_meta(module_id), | ||||
|                         ), | ||||
|                     }; | ||||
|                     functions.push(def); | ||||
|                 } | ||||
| @ -75,14 +78,14 @@ impl ast::Module { | ||||
|                                             StructField( | ||||
|                                                 s.name.clone(), | ||||
|                                                 s.ty.clone().into(), | ||||
|                                                 s.range.into(), | ||||
|                                                 s.range.as_meta(module_id), | ||||
|                                             ) | ||||
|                                         }) | ||||
|                                         .collect(), | ||||
|                                 )) | ||||
|                             } | ||||
|                         }, | ||||
|                         meta: (*range).into(), | ||||
|                         meta: (*range).as_meta(module_id), | ||||
|                     }; | ||||
|                     typedefs.push(def); | ||||
|                 } | ||||
| @ -91,6 +94,7 @@ impl ast::Module { | ||||
| 
 | ||||
|         mir::Module { | ||||
|             name: self.name.clone(), | ||||
|             module_id: module_id, | ||||
|             imports, | ||||
|             functions, | ||||
|             path: self.path.clone(), | ||||
| @ -101,7 +105,7 @@ impl ast::Module { | ||||
| } | ||||
| 
 | ||||
| impl ast::Block { | ||||
|     pub fn into_mir(&self) -> mir::Block { | ||||
|     pub fn into_mir(&self, module_id: SourceModuleId) -> mir::Block { | ||||
|         let mut mir_statements = Vec::new(); | ||||
| 
 | ||||
|         for statement in &self.0 { | ||||
| @ -115,27 +119,31 @@ impl ast::Block { | ||||
|                                 .map(|t| t.0.into()) | ||||
|                                 .unwrap_or(mir::TypeKind::Vague(mir::VagueType::Unknown)), | ||||
|                             s_let.0.clone(), | ||||
|                             s_let.4.into(), | ||||
|                             s_let.4.as_meta(module_id), | ||||
|                         ), | ||||
|                         s_let.2, | ||||
|                         s_let.3.process(), | ||||
|                         s_let.3.process(module_id), | ||||
|                     ), | ||||
|                     s_let.4, | ||||
|                 ), | ||||
|                 ast::BlockLevelStatement::Set(var_ref, expression, range) => ( | ||||
|                     StmtKind::Set(var_ref.process(), expression.process()), | ||||
|                     StmtKind::Set(var_ref.process(module_id), expression.process(module_id)), | ||||
|                     *range, | ||||
|                 ), | ||||
|                 ast::BlockLevelStatement::Import { _i } => todo!(), | ||||
|                 ast::BlockLevelStatement::Expression(e) => (StmtKind::Expression(e.process()), e.1), | ||||
|                 ast::BlockLevelStatement::Return(_, e) => (StmtKind::Expression(e.process()), e.1), | ||||
|                 ast::BlockLevelStatement::Expression(e) => { | ||||
|                     (StmtKind::Expression(e.process(module_id)), e.1) | ||||
|                 } | ||||
|                 ast::BlockLevelStatement::Return(_, e) => { | ||||
|                     (StmtKind::Expression(e.process(module_id)), e.1) | ||||
|                 } | ||||
|             }; | ||||
| 
 | ||||
|             mir_statements.push(mir::Statement(kind, range.into())); | ||||
|             mir_statements.push(mir::Statement(kind, range.as_meta(module_id))); | ||||
|         } | ||||
| 
 | ||||
|         let return_expression = if let Some(r) = &self.1 { | ||||
|             Some((r.0.into(), Box::new(r.1.process()))) | ||||
|             Some((r.0.into(), Box::new(r.1.process(module_id)))) | ||||
|         } else { | ||||
|             None | ||||
|         }; | ||||
| @ -143,7 +151,7 @@ impl ast::Block { | ||||
|         mir::Block { | ||||
|             statements: mir_statements, | ||||
|             return_expression, | ||||
|             meta: self.2.into(), | ||||
|             meta: self.2.as_meta(module_id), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -158,61 +166,67 @@ impl From<ast::ReturnType> for mir::ReturnKind { | ||||
| } | ||||
| 
 | ||||
| impl ast::Expression { | ||||
|     fn process(&self) -> mir::Expression { | ||||
|     fn process(&self, module_id: SourceModuleId) -> mir::Expression { | ||||
|         let kind = match &self.0 { | ||||
|             ast::ExpressionKind::VariableName(name) => mir::ExprKind::Variable(NamedVariableRef( | ||||
|                 mir::TypeKind::Vague(mir::VagueType::Unknown), | ||||
|                 name.clone(), | ||||
|                 self.1.into(), | ||||
|                 self.1.as_meta(module_id), | ||||
|             )), | ||||
|             ast::ExpressionKind::Literal(literal) => mir::ExprKind::Literal(literal.mir()), | ||||
|             ast::ExpressionKind::Binop(binary_operator, lhs, rhs) => mir::ExprKind::BinOp( | ||||
|                 binary_operator.mir(), | ||||
|                 Box::new(lhs.process()), | ||||
|                 Box::new(rhs.process()), | ||||
|                 Box::new(lhs.process(module_id)), | ||||
|                 Box::new(rhs.process(module_id)), | ||||
|             ), | ||||
|             ast::ExpressionKind::FunctionCall(fn_call_expr) => { | ||||
|                 mir::ExprKind::FunctionCall(mir::FunctionCall { | ||||
|                     name: fn_call_expr.0.clone(), | ||||
|                     return_type: mir::TypeKind::Vague(mir::VagueType::Unknown), | ||||
|                     parameters: fn_call_expr.1.iter().map(|e| e.process()).collect(), | ||||
|                     parameters: fn_call_expr | ||||
|                         .1 | ||||
|                         .iter() | ||||
|                         .map(|e| e.process(module_id)) | ||||
|                         .collect(), | ||||
|                 }) | ||||
|             } | ||||
|             ast::ExpressionKind::BlockExpr(block) => mir::ExprKind::Block(block.into_mir()), | ||||
|             ast::ExpressionKind::BlockExpr(block) => { | ||||
|                 mir::ExprKind::Block(block.into_mir(module_id)) | ||||
|             } | ||||
|             ast::ExpressionKind::IfExpr(if_expression) => { | ||||
|                 let cond = if_expression.0.process(); | ||||
|                 let then_block = if_expression.1.into_mir(); | ||||
|                 let cond = if_expression.0.process(module_id); | ||||
|                 let then_block = if_expression.1.into_mir(module_id); | ||||
|                 let else_block = if let Some(el) = &if_expression.2 { | ||||
|                     Some(el.into_mir()) | ||||
|                     Some(el.into_mir(module_id)) | ||||
|                 } else { | ||||
|                     None | ||||
|                 }; | ||||
|                 mir::ExprKind::If(mir::IfExpression(Box::new(cond), then_block, else_block)) | ||||
|             } | ||||
|             ast::ExpressionKind::Array(expressions) => { | ||||
|                 mir::ExprKind::Array(expressions.iter().map(|e| e.process()).collect()) | ||||
|                 mir::ExprKind::Array(expressions.iter().map(|e| e.process(module_id)).collect()) | ||||
|             } | ||||
|             ast::ExpressionKind::Indexed(expression, idx_expr) => mir::ExprKind::Indexed( | ||||
|                 Box::new(expression.process()), | ||||
|                 Box::new(expression.process(module_id)), | ||||
|                 mir::TypeKind::Vague(mir::VagueType::Unknown), | ||||
|                 Box::new(idx_expr.process()), | ||||
|                 Box::new(idx_expr.process(module_id)), | ||||
|             ), | ||||
|             ast::ExpressionKind::StructExpression(struct_init) => mir::ExprKind::Struct( | ||||
|                 struct_init.name.clone(), | ||||
|                 struct_init | ||||
|                     .fields | ||||
|                     .iter() | ||||
|                     .map(|(n, e)| (n.clone(), e.process())) | ||||
|                     .map(|(n, e)| (n.clone(), e.process(module_id))) | ||||
|                     .collect(), | ||||
|             ), | ||||
|             ast::ExpressionKind::Accessed(expression, name) => mir::ExprKind::Accessed( | ||||
|                 Box::new(expression.process()), | ||||
|                 Box::new(expression.process(module_id)), | ||||
|                 mir::TypeKind::Vague(mir::VagueType::Unknown), | ||||
|                 name.clone(), | ||||
|             ), | ||||
|         }; | ||||
| 
 | ||||
|         mir::Expression(kind, self.1.into()) | ||||
|         mir::Expression(kind, self.1.as_meta(module_id)) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										0
									
								
								reid/src/error_raporting.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								reid/src/error_raporting.rs
									
									
									
									
									
										Normal file
									
								
							| @ -45,6 +45,7 @@ use std::path::PathBuf; | ||||
| 
 | ||||
| use mir::{ | ||||
|     linker::LinkerPass, typecheck::TypeCheck, typeinference::TypeInference, typerefs::TypeRefs, | ||||
|     SourceModuleId, | ||||
| }; | ||||
| use reid_lib::{compile::CompileOutput, Context}; | ||||
| 
 | ||||
| @ -75,6 +76,7 @@ pub enum ReidError { | ||||
| pub fn compile_module( | ||||
|     source: &str, | ||||
|     name: String, | ||||
|     module_id: SourceModuleId, | ||||
|     path: Option<PathBuf>, | ||||
|     is_main: bool, | ||||
| ) -> Result<mir::Module, ReidError> { | ||||
| @ -99,7 +101,7 @@ pub fn compile_module( | ||||
|         is_main, | ||||
|     }; | ||||
| 
 | ||||
|     Ok(ast_module.process()) | ||||
|     Ok(ast_module.process(module_id)) | ||||
| } | ||||
| 
 | ||||
| pub fn perform_all_passes(context: &mut mir::Context) -> Result<(), ReidError> { | ||||
| @ -159,6 +161,7 @@ pub fn compile(source: &str, path: PathBuf) -> Result<CompileOutput, ReidError> | ||||
|         vec![compile_module( | ||||
|             source, | ||||
|             path.file_name().unwrap().to_str().unwrap().to_owned(), | ||||
|             SourceModuleId::default(), | ||||
|             Some(path.clone()), | ||||
|             true, | ||||
|         )?], | ||||
|  | ||||
| @ -289,7 +289,13 @@ impl Display for CmpOperator { | ||||
| 
 | ||||
| impl Display for Metadata { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         write!(f, "{:?}", self.range) | ||||
|         write!(f, "{:?} ({})", self.range, self.source_module_id) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Display for SourceModuleId { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         write!(f, "Mod {}", self.0) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,4 +1,8 @@ | ||||
| use super::{typecheck::ErrorKind, typerefs::TypeRefs, VagueType as Vague, *}; | ||||
| use super::{ | ||||
|     typecheck::ErrorKind, | ||||
|     typerefs::{ScopeTypeRefs, TypeRef, TypeRefs}, | ||||
|     VagueType as Vague, *, | ||||
| }; | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub enum ReturnTypeOther { | ||||
|  | ||||
| @ -12,7 +12,7 @@ use crate::{compile_module, ReidError}; | ||||
| use super::{ | ||||
|     pass::{Pass, PassState}, | ||||
|     r#impl::EqualsIssue, | ||||
|     Context, FunctionDefinition, Import, Metadata, Module, | ||||
|     Context, FunctionDefinition, Import, Metadata, Module, SourceModuleId, | ||||
| }; | ||||
| 
 | ||||
| pub static STD_SOURCE: &str = include_str!("../../lib/std.reid"); | ||||
| @ -41,8 +41,15 @@ pub enum ErrorKind { | ||||
|     FunctionIsPrivate(String, String), | ||||
| } | ||||
| 
 | ||||
| pub fn compile_std() -> super::Module { | ||||
|     let module = compile_module(STD_SOURCE, "standard_library".to_owned(), None, false).unwrap(); | ||||
| pub fn compile_std(module_id: SourceModuleId) -> super::Module { | ||||
|     let module = compile_module( | ||||
|         STD_SOURCE, | ||||
|         "standard_library".to_owned(), | ||||
|         module_id, | ||||
|         None, | ||||
|         false, | ||||
|     ) | ||||
|     .unwrap(); | ||||
| 
 | ||||
|     let mut mir_context = super::Context::from(vec![module], Default::default()); | ||||
| 
 | ||||
| @ -85,7 +92,16 @@ impl Pass for LinkerPass { | ||||
|             modules.insert(module.name.clone(), Rc::new(RefCell::new(module))); | ||||
|         } | ||||
| 
 | ||||
|         modules.insert("std".to_owned(), Rc::new(RefCell::new(compile_std()))); | ||||
|         let mut module_counter = modules | ||||
|             .values() | ||||
|             .map(|m| m.borrow().module_id) | ||||
|             .max() | ||||
|             .unwrap(); | ||||
| 
 | ||||
|         modules.insert( | ||||
|             "std".to_owned(), | ||||
|             Rc::new(RefCell::new(compile_std(module_counter.increment()))), | ||||
|         ); | ||||
| 
 | ||||
|         let mut modules_to_process: Vec<Rc<RefCell<Module>>> = modules.values().cloned().collect(); | ||||
| 
 | ||||
| @ -117,7 +133,13 @@ impl Pass for LinkerPass { | ||||
|                         continue; | ||||
|                     }; | ||||
| 
 | ||||
|                     match compile_module(&source, module_name.clone(), Some(file_path), false) { | ||||
|                     match compile_module( | ||||
|                         &source, | ||||
|                         module_name.clone(), | ||||
|                         module_counter.increment(), | ||||
|                         Some(file_path), | ||||
|                         false, | ||||
|                     ) { | ||||
|                         Ok(imported_module) => { | ||||
|                             if imported_module.is_main { | ||||
|                                 state.ok::<_, Infallible>( | ||||
|  | ||||
| @ -14,24 +14,40 @@ pub mod typecheck; | ||||
| pub mod typeinference; | ||||
| pub mod typerefs; | ||||
| 
 | ||||
| #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)] | ||||
| pub struct SourceModuleId(u32); | ||||
| 
 | ||||
| impl SourceModuleId { | ||||
|     pub fn increment(&mut self) -> SourceModuleId { | ||||
|         self.0 += 1; | ||||
|         SourceModuleId(self.0) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Default, Clone, Copy)] | ||||
| pub struct Metadata { | ||||
|     pub range: TokenRange, | ||||
|     pub source_module_id: SourceModuleId, | ||||
| } | ||||
| 
 | ||||
| impl std::ops::Add for Metadata { | ||||
|     type Output = Metadata; | ||||
| 
 | ||||
|     fn add(self, rhs: Self) -> Self::Output { | ||||
|         assert!(self.source_module_id == rhs.source_module_id); | ||||
|         Metadata { | ||||
|             range: self.range + rhs.range, | ||||
|             source_module_id: self.source_module_id, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<TokenRange> for Metadata { | ||||
|     fn from(value: TokenRange) -> Self { | ||||
|         Metadata { range: value } | ||||
| impl TokenRange { | ||||
|     pub fn as_meta(self, module: SourceModuleId) -> Metadata { | ||||
|         Metadata { | ||||
|             range: self, | ||||
|             source_module_id: module, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -240,14 +256,14 @@ pub enum FunctionDefinitionKind { | ||||
| impl FunctionDefinition { | ||||
|     fn block_meta(&self) -> Metadata { | ||||
|         match &self.kind { | ||||
|             FunctionDefinitionKind::Local(block, _) => block.meta, | ||||
|             FunctionDefinitionKind::Local(block, _) => block.meta.clone(), | ||||
|             FunctionDefinitionKind::Extern(_) => Metadata::default(), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn signature(&self) -> Metadata { | ||||
|         match &self.kind { | ||||
|             FunctionDefinitionKind::Local(_, metadata) => *metadata, | ||||
|             FunctionDefinitionKind::Local(_, metadata) => metadata.clone(), | ||||
|             FunctionDefinitionKind::Extern(_) => Metadata::default(), | ||||
|         } | ||||
|     } | ||||
| @ -288,6 +304,7 @@ pub enum TypeDefinitionKind { | ||||
| #[derive(Debug)] | ||||
| pub struct Module { | ||||
|     pub name: String, | ||||
|     pub module_id: SourceModuleId, | ||||
|     pub imports: Vec<Import>, | ||||
|     pub functions: Vec<FunctionDefinition>, | ||||
|     pub typedefs: Vec<TypeDefinition>, | ||||
|  | ||||
| @ -15,7 +15,13 @@ pub static STRINGS: &str = include_str!("../../reid_src/strings.reid"); | ||||
| 
 | ||||
| #[test] | ||||
| fn array_compiles_well() { | ||||
|     let module = assert_err(compile_module(ARRAY, "array".to_owned(), None, true)); | ||||
|     let module = assert_err(compile_module( | ||||
|         ARRAY, | ||||
|         "array".to_owned(), | ||||
|         Default::default(), | ||||
|         None, | ||||
|         true, | ||||
|     )); | ||||
| 
 | ||||
|     assert_err(perform_all_passes(&mut mir::Context { | ||||
|         modules: vec![module], | ||||
| @ -28,6 +34,7 @@ fn fibonacci_compiles_well() { | ||||
|     let module = assert_err(compile_module( | ||||
|         FIBONACCI, | ||||
|         "fibonacci".to_owned(), | ||||
|         Default::default(), | ||||
|         None, | ||||
|         true, | ||||
|     )); | ||||
| @ -43,6 +50,7 @@ fn hello_world_compiles_well() { | ||||
|     let module = assert_err(compile_module( | ||||
|         HELLO_WORLD, | ||||
|         "hello_world".to_owned(), | ||||
|         Default::default(), | ||||
|         None, | ||||
|         true, | ||||
|     )); | ||||
| @ -55,7 +63,13 @@ fn hello_world_compiles_well() { | ||||
| 
 | ||||
| #[test] | ||||
| fn mutable_compiles_well() { | ||||
|     let module = assert_err(compile_module(MUTABLE, "mutable".to_owned(), None, true)); | ||||
|     let module = assert_err(compile_module( | ||||
|         MUTABLE, | ||||
|         "mutable".to_owned(), | ||||
|         Default::default(), | ||||
|         None, | ||||
|         true, | ||||
|     )); | ||||
| 
 | ||||
|     assert_err(perform_all_passes(&mut mir::Context { | ||||
|         modules: vec![module], | ||||
| @ -65,7 +79,13 @@ fn mutable_compiles_well() { | ||||
| 
 | ||||
| #[test] | ||||
| fn strings_compiles_well() { | ||||
|     let module = assert_err(compile_module(STRINGS, "strings".to_owned(), None, true)); | ||||
|     let module = assert_err(compile_module( | ||||
|         STRINGS, | ||||
|         "strings".to_owned(), | ||||
|         Default::default(), | ||||
|         None, | ||||
|         true, | ||||
|     )); | ||||
| 
 | ||||
|     assert_err(perform_all_passes(&mut mir::Context { | ||||
|         modules: vec![module], | ||||
|  | ||||
| @ -8,12 +8,12 @@ mod util; | ||||
| 
 | ||||
| #[test] | ||||
| fn compiles() { | ||||
|     let _ = compile_std(); | ||||
|     let _ = compile_std(Default::default()); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn passes_all_passes() { | ||||
|     let mut std = compile_std(); | ||||
|     let mut std = compile_std(Default::default()); | ||||
| 
 | ||||
|     // Needed to pass linker-pass
 | ||||
|     std.is_main = true; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user