Make passes actually return errors well
This commit is contained in:
		
							parent
							
								
									e4845c4084
								
							
						
					
					
						commit
						575abe8172
					
				| @ -41,6 +41,9 @@ Currently missing relevant features (TODOs) are: | |||||||
| - Debug Information | - Debug Information | ||||||
| - Borrows+Pointers | - Borrows+Pointers | ||||||
| 
 | 
 | ||||||
|  | Smaller features: | ||||||
|  | - Easier way to initialize arrays with a single value | ||||||
|  | 
 | ||||||
| ### Why "Reid" | ### Why "Reid" | ||||||
| 
 | 
 | ||||||
| [ᚱ is an Elder Futhark rune](https://en.wikipedia.org/wiki/Raido) which means | [ᚱ is an Elder Futhark rune](https://en.wikipedia.org/wiki/Raido) which means | ||||||
|  | |||||||
| @ -1,10 +1,21 @@ | |||||||
| 
 | 
 | ||||||
| extern fn puts(message: string) -> i32; | extern fn puts(message: string) -> i32; | ||||||
| 
 | 
 | ||||||
|  | struct DivT { | ||||||
|  |     quot: i32, | ||||||
|  |     rem: i32, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | extern fn div(numerator: i32, denominator: i32) -> DivT; | ||||||
|  | 
 | ||||||
| pub fn print(message: string) { | pub fn print(message: string) { | ||||||
|     puts(message); |     puts(message); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | pub fn intdiv(numerator: i32, denominator: i32) -> DivT { | ||||||
|  |     return div(numerator, denominator); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| fn main() -> u16 { | fn main() -> u16 { | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  | |||||||
| @ -121,7 +121,7 @@ pub fn perform_all_passes<'map>( | |||||||
|     #[cfg(debug_assertions)] |     #[cfg(debug_assertions)] | ||||||
|     println!("{}", &context); |     println!("{}", &context); | ||||||
| 
 | 
 | ||||||
|     let state = context.pass(&mut LinkerPass { module_map }); |     let state = context.pass(&mut LinkerPass { module_map })?; | ||||||
| 
 | 
 | ||||||
|     #[cfg(debug_assertions)] |     #[cfg(debug_assertions)] | ||||||
|     println!("{}", &context); |     println!("{}", &context); | ||||||
| @ -137,7 +137,7 @@ pub fn perform_all_passes<'map>( | |||||||
| 
 | 
 | ||||||
|     let refs = TypeRefs::default(); |     let refs = TypeRefs::default(); | ||||||
| 
 | 
 | ||||||
|     let state = context.pass(&mut TypeInference { refs: &refs }); |     let state = context.pass(&mut TypeInference { refs: &refs })?; | ||||||
| 
 | 
 | ||||||
|     #[cfg(debug_assertions)] |     #[cfg(debug_assertions)] | ||||||
|     dbg!(&refs); |     dbg!(&refs); | ||||||
| @ -157,7 +157,7 @@ pub fn perform_all_passes<'map>( | |||||||
|         )); |         )); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     let state = context.pass(&mut TypeCheck { refs: &refs }); |     let state = context.pass(&mut TypeCheck { refs: &refs })?; | ||||||
| 
 | 
 | ||||||
|     #[cfg(debug_assertions)] |     #[cfg(debug_assertions)] | ||||||
|     println!("{}", &context); |     println!("{}", &context); | ||||||
| @ -189,13 +189,19 @@ pub fn compile_and_pass<'map>( | |||||||
|     let path = path.canonicalize().unwrap(); |     let path = path.canonicalize().unwrap(); | ||||||
|     let name = path.file_name().unwrap().to_str().unwrap().to_owned(); |     let name = path.file_name().unwrap().to_str().unwrap().to_owned(); | ||||||
| 
 | 
 | ||||||
|     let (id, tokens) = parse_module(source, name, module_map).unwrap(); |     let (id, tokens) = parse_module(source, name, module_map)?; | ||||||
|     let module = compile_module(id, &tokens, module_map, Some(path.clone()), true)?; |     let module = compile_module(id, &tokens, module_map, Some(path.clone()), true)?; | ||||||
| 
 | 
 | ||||||
|     let mut mir_context = mir::Context::from(vec![module], path.parent().unwrap().to_owned()); |     let mut mir_context = mir::Context::from(vec![module], path.parent().unwrap().to_owned()); | ||||||
| 
 | 
 | ||||||
|  |     dbg!(&mir_context); | ||||||
|  |     println!("Context: {}", &mir_context); | ||||||
|  | 
 | ||||||
|     perform_all_passes(&mut mir_context, module_map)?; |     perform_all_passes(&mut mir_context, module_map)?; | ||||||
| 
 | 
 | ||||||
|  |     dbg!(&mir_context); | ||||||
|  |     println!("Context: {}", &mir_context); | ||||||
|  | 
 | ||||||
|     let mut context = Context::new(format!("Reid ({})", env!("CARGO_PKG_VERSION"))); |     let mut context = Context::new(format!("Reid ({})", env!("CARGO_PKG_VERSION"))); | ||||||
|     let codegen_modules = mir_context.codegen(&mut context, &module_map); |     let codegen_modules = mir_context.codegen(&mut context, &module_map); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -7,10 +7,15 @@ use std::{ | |||||||
|     rc::Rc, |     rc::Rc, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| use crate::{compile_module, error_raporting::ModuleMap, lexer::FullToken, parse_module}; | use crate::{ | ||||||
|  |     compile_module, | ||||||
|  |     error_raporting::{ModuleMap, ReidError}, | ||||||
|  |     lexer::FullToken, | ||||||
|  |     parse_module, | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| use super::{ | use super::{ | ||||||
|     pass::{Pass, PassState}, |     pass::{Pass, PassResult, PassState}, | ||||||
|     r#impl::EqualsIssue, |     r#impl::EqualsIssue, | ||||||
|     Context, FunctionDefinition, Import, Metadata, Module, |     Context, FunctionDefinition, Import, Metadata, Module, | ||||||
| }; | }; | ||||||
| @ -41,14 +46,16 @@ pub enum ErrorKind { | |||||||
|     FunctionIsPrivate(String, String), |     FunctionIsPrivate(String, String), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn compile_std(module_map: &mut ModuleMap) -> (super::Module, Vec<FullToken>) { | pub fn compile_std( | ||||||
|     let (id, tokens) = parse_module(STD_SOURCE, "standard_library", module_map).unwrap(); |     module_map: &mut ModuleMap, | ||||||
|     let module = compile_module(id, &tokens, module_map, None, false).unwrap(); | ) -> Result<(super::Module, Vec<FullToken>), ReidError> { | ||||||
|  |     let (id, tokens) = parse_module(STD_SOURCE, "standard_library", module_map)?; | ||||||
|  |     let module = compile_module(id, &tokens, module_map, None, false)?; | ||||||
| 
 | 
 | ||||||
|     let mut mir_context = super::Context::from(vec![module], Default::default()); |     let mut mir_context = super::Context::from(vec![module], Default::default()); | ||||||
| 
 | 
 | ||||||
|     let std_compiled = mir_context.modules.remove(0); |     let std_compiled = mir_context.modules.remove(0); | ||||||
|     (std_compiled, tokens) |     Ok((std_compiled, tokens)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Struct used to implement a type-checking pass that can be performed on the
 | /// Struct used to implement a type-checking pass that can be performed on the
 | ||||||
| @ -62,7 +69,7 @@ type LinkerPassState<'st, 'sc> = PassState<'st, 'sc, (), ErrorKind>; | |||||||
| impl<'map> Pass for LinkerPass<'map> { | impl<'map> Pass for LinkerPass<'map> { | ||||||
|     type Data = (); |     type Data = (); | ||||||
|     type TError = ErrorKind; |     type TError = ErrorKind; | ||||||
|     fn context(&mut self, context: &mut Context, mut state: LinkerPassState) { |     fn context(&mut self, context: &mut Context, mut state: LinkerPassState) -> PassResult { | ||||||
|         let mains = context |         let mains = context | ||||||
|             .modules |             .modules | ||||||
|             .iter() |             .iter() | ||||||
| @ -70,16 +77,16 @@ impl<'map> Pass for LinkerPass<'map> { | |||||||
|             .collect::<Vec<_>>(); |             .collect::<Vec<_>>(); | ||||||
|         if mains.len() > 1 { |         if mains.len() > 1 { | ||||||
|             state.note_errors(&vec![ErrorKind::MultipleMainsAtStart], Metadata::default()); |             state.note_errors(&vec![ErrorKind::MultipleMainsAtStart], Metadata::default()); | ||||||
|             return; |             return Ok(()); | ||||||
|         } |         } | ||||||
|         let Some(main) = mains.first() else { |         let Some(main) = mains.first() else { | ||||||
|             state.note_errors(&vec![ErrorKind::NoMainDefined], Metadata::default()); |             state.note_errors(&vec![ErrorKind::NoMainDefined], Metadata::default()); | ||||||
|             return; |             return Ok(()); | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         let Some(_) = main.functions.iter().find(|f| f.name == "main") else { |         let Some(_) = main.functions.iter().find(|f| f.name == "main") else { | ||||||
|             state.note_errors(&vec![ErrorKind::NoMainFunction], Metadata::default()); |             state.note_errors(&vec![ErrorKind::NoMainFunction], Metadata::default()); | ||||||
|             return; |             return Ok(()); | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         let mut modules = HashMap::<String, Rc<RefCell<_>>>::new(); |         let mut modules = HashMap::<String, Rc<RefCell<_>>>::new(); | ||||||
| @ -95,10 +102,10 @@ impl<'map> Pass for LinkerPass<'map> { | |||||||
|             modules.insert(module.name.clone(), Rc::new(RefCell::new((module, tokens)))); |             modules.insert(module.name.clone(), Rc::new(RefCell::new((module, tokens)))); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // modules.insert(
 |         modules.insert( | ||||||
|         //     "std".to_owned(),
 |             "std".to_owned(), | ||||||
|         //     Rc::new(RefCell::new(compile_std(&mut self.module_map))),
 |             Rc::new(RefCell::new(compile_std(&mut self.module_map)?)), | ||||||
|         // );
 |         ); | ||||||
| 
 | 
 | ||||||
|         let mut modules_to_process: Vec<Rc<RefCell<(Module, Vec<FullToken>)>>> = |         let mut modules_to_process: Vec<Rc<RefCell<(Module, Vec<FullToken>)>>> = | ||||||
|             modules.values().cloned().collect(); |             modules.values().cloned().collect(); | ||||||
| @ -243,5 +250,7 @@ impl<'map> Pass for LinkerPass<'map> { | |||||||
|             .into_values() |             .into_values() | ||||||
|             .map(|v| Rc::into_inner(v).unwrap().into_inner().0) |             .map(|v| Rc::into_inner(v).unwrap().into_inner().0) | ||||||
|             .collect(); |             .collect(); | ||||||
|  | 
 | ||||||
|  |         Ok(()) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -5,6 +5,8 @@ use std::collections::HashMap; | |||||||
| use std::convert::Infallible; | use std::convert::Infallible; | ||||||
| use std::error::Error as STDError; | use std::error::Error as STDError; | ||||||
| 
 | 
 | ||||||
|  | use crate::error_raporting::ReidError; | ||||||
|  | 
 | ||||||
| use super::*; | use super::*; | ||||||
| 
 | 
 | ||||||
| #[derive(thiserror::Error, Debug, Clone)] | #[derive(thiserror::Error, Debug, Clone)] | ||||||
| @ -205,33 +207,65 @@ impl<'st, 'sc, Data: Clone + Default, TError: STDError + Clone> PassState<'st, ' | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | pub type PassResult = Result<(), ReidError>; | ||||||
|  | 
 | ||||||
| pub trait Pass { | pub trait Pass { | ||||||
|     type Data: Clone + Default; |     type Data: Clone + Default; | ||||||
|     type TError: STDError + Clone; |     type TError: STDError + Clone; | ||||||
| 
 | 
 | ||||||
|     fn context(&mut self, _context: &mut Context, mut _state: PassState<Self::Data, Self::TError>) { |     fn context( | ||||||
|  |         &mut self, | ||||||
|  |         _context: &mut Context, | ||||||
|  |         mut _state: PassState<Self::Data, Self::TError>, | ||||||
|  |     ) -> PassResult { | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  |     fn module( | ||||||
|  |         &mut self, | ||||||
|  |         _module: &mut Module, | ||||||
|  |         mut _state: PassState<Self::Data, Self::TError>, | ||||||
|  |     ) -> PassResult { | ||||||
|  |         Ok(()) | ||||||
|     } |     } | ||||||
|     fn module(&mut self, _module: &mut Module, mut _state: PassState<Self::Data, Self::TError>) {} |  | ||||||
|     fn function( |     fn function( | ||||||
|         &mut self, |         &mut self, | ||||||
|         _function: &mut FunctionDefinition, |         _function: &mut FunctionDefinition, | ||||||
|         mut _state: PassState<Self::Data, Self::TError>, |         mut _state: PassState<Self::Data, Self::TError>, | ||||||
|     ) { |     ) -> PassResult { | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  |     fn block( | ||||||
|  |         &mut self, | ||||||
|  |         _block: &mut Block, | ||||||
|  |         mut _state: PassState<Self::Data, Self::TError>, | ||||||
|  |     ) -> PassResult { | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  |     fn stmt( | ||||||
|  |         &mut self, | ||||||
|  |         _stmt: &mut Statement, | ||||||
|  |         mut _state: PassState<Self::Data, Self::TError>, | ||||||
|  |     ) -> PassResult { | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  |     fn expr( | ||||||
|  |         &mut self, | ||||||
|  |         _expr: &mut Expression, | ||||||
|  |         mut _state: PassState<Self::Data, Self::TError>, | ||||||
|  |     ) -> PassResult { | ||||||
|  |         Ok(()) | ||||||
|     } |     } | ||||||
|     fn block(&mut self, _block: &mut Block, mut _state: PassState<Self::Data, Self::TError>) {} |  | ||||||
|     fn stmt(&mut self, _stmt: &mut Statement, mut _state: PassState<Self::Data, Self::TError>) {} |  | ||||||
|     fn expr(&mut self, _expr: &mut Expression, mut _state: PassState<Self::Data, Self::TError>) {} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Context { | impl Context { | ||||||
|     pub fn pass<T: Pass>(&mut self, pass: &mut T) -> State<T::TError> { |     pub fn pass<T: Pass>(&mut self, pass: &mut T) -> Result<State<T::TError>, ReidError> { | ||||||
|         let mut state = State::new(); |         let mut state = State::new(); | ||||||
|         let mut scope = Scope::default(); |         let mut scope = Scope::default(); | ||||||
|         pass.context(self, PassState::from(&mut state, &mut scope)); |         pass.context(self, PassState::from(&mut state, &mut scope))?; | ||||||
|         for module in &mut self.modules { |         for module in &mut self.modules { | ||||||
|             module.pass(pass, &mut state, &mut scope.inner()); |             module.pass(pass, &mut state, &mut scope.inner())?; | ||||||
|         } |         } | ||||||
|         state |         Ok(state) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -241,7 +275,7 @@ impl Module { | |||||||
|         pass: &mut T, |         pass: &mut T, | ||||||
|         state: &mut State<T::TError>, |         state: &mut State<T::TError>, | ||||||
|         scope: &mut Scope<T::Data>, |         scope: &mut Scope<T::Data>, | ||||||
|     ) { |     ) -> PassResult { | ||||||
|         for typedef in &self.typedefs { |         for typedef in &self.typedefs { | ||||||
|             let kind = match &typedef.kind { |             let kind = match &typedef.kind { | ||||||
|                 TypeDefinitionKind::Struct(fields) => TypeDefinitionKind::Struct(fields.clone()), |                 TypeDefinitionKind::Struct(fields) => TypeDefinitionKind::Struct(fields.clone()), | ||||||
| @ -262,11 +296,12 @@ impl Module { | |||||||
|                 .ok(); |                 .ok(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         pass.module(self, PassState::from(state, scope)); |         pass.module(self, PassState::from(state, scope))?; | ||||||
| 
 | 
 | ||||||
|         for function in &mut self.functions { |         for function in &mut self.functions { | ||||||
|             function.pass(pass, state, &mut scope.inner()); |             function.pass(pass, state, &mut scope.inner())?; | ||||||
|         } |         } | ||||||
|  |         Ok(()) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -276,7 +311,7 @@ impl FunctionDefinition { | |||||||
|         pass: &mut T, |         pass: &mut T, | ||||||
|         state: &mut State<T::TError>, |         state: &mut State<T::TError>, | ||||||
|         scope: &mut Scope<T::Data>, |         scope: &mut Scope<T::Data>, | ||||||
|     ) { |     ) -> PassResult { | ||||||
|         for param in &self.parameters { |         for param in &self.parameters { | ||||||
|             scope |             scope | ||||||
|                 .variables |                 .variables | ||||||
| @ -290,15 +325,16 @@ impl FunctionDefinition { | |||||||
|                 .ok(); |                 .ok(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         pass.function(self, PassState::from(state, scope)); |         pass.function(self, PassState::from(state, scope))?; | ||||||
| 
 | 
 | ||||||
|         match &mut self.kind { |         match &mut self.kind { | ||||||
|             FunctionDefinitionKind::Local(block, _) => { |             FunctionDefinitionKind::Local(block, _) => { | ||||||
|                 scope.return_type_hint = Some(self.return_type.clone()); |                 scope.return_type_hint = Some(self.return_type.clone()); | ||||||
|                 block.pass(pass, state, scope); |                 block.pass(pass, state, scope)?; | ||||||
|             } |             } | ||||||
|             FunctionDefinitionKind::Extern(_) => {} |             FunctionDefinitionKind::Extern(_) => {} | ||||||
|         }; |         }; | ||||||
|  |         Ok(()) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -308,14 +344,14 @@ impl Block { | |||||||
|         pass: &mut T, |         pass: &mut T, | ||||||
|         state: &mut State<T::TError>, |         state: &mut State<T::TError>, | ||||||
|         scope: &mut Scope<T::Data>, |         scope: &mut Scope<T::Data>, | ||||||
|     ) { |     ) -> PassResult { | ||||||
|         let mut scope = scope.inner(); |         let mut scope = scope.inner(); | ||||||
| 
 | 
 | ||||||
|         for statement in &mut self.statements { |         for statement in &mut self.statements { | ||||||
|             statement.pass(pass, state, &mut scope); |             statement.pass(pass, state, &mut scope)?; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         pass.block(self, PassState::from(state, &mut scope)); |         pass.block(self, PassState::from(state, &mut scope)) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -325,21 +361,21 @@ impl Statement { | |||||||
|         pass: &mut T, |         pass: &mut T, | ||||||
|         state: &mut State<T::TError>, |         state: &mut State<T::TError>, | ||||||
|         scope: &mut Scope<T::Data>, |         scope: &mut Scope<T::Data>, | ||||||
|     ) { |     ) -> PassResult { | ||||||
|         match &mut self.0 { |         match &mut self.0 { | ||||||
|             StmtKind::Let(_, _, expression) => { |             StmtKind::Let(_, _, expression) => { | ||||||
|                 expression.pass(pass, state, scope); |                 expression.pass(pass, state, scope)?; | ||||||
|             } |             } | ||||||
|             StmtKind::Set(_, expression) => { |             StmtKind::Set(_, expression) => { | ||||||
|                 expression.pass(pass, state, scope); |                 expression.pass(pass, state, scope)?; | ||||||
|             } |             } | ||||||
|             StmtKind::Import(_) => {} // Never exists at this stage
 |             StmtKind::Import(_) => {} // Never exists at this stage
 | ||||||
|             StmtKind::Expression(expression) => { |             StmtKind::Expression(expression) => { | ||||||
|                 expression.pass(pass, state, scope); |                 expression.pass(pass, state, scope)?; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         pass.stmt(self, PassState::from(state, scope)); |         pass.stmt(self, PassState::from(state, scope))?; | ||||||
| 
 | 
 | ||||||
|         match &mut self.0 { |         match &mut self.0 { | ||||||
|             StmtKind::Let(variable_reference, mutable, _) => { |             StmtKind::Let(variable_reference, mutable, _) => { | ||||||
| @ -358,6 +394,7 @@ impl Statement { | |||||||
|             StmtKind::Import(_) => {} // Never exists at this stage
 |             StmtKind::Import(_) => {} // Never exists at this stage
 | ||||||
|             StmtKind::Expression(_) => {} |             StmtKind::Expression(_) => {} | ||||||
|         }; |         }; | ||||||
|  |         Ok(()) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -367,7 +404,8 @@ impl Expression { | |||||||
|         pass: &mut T, |         pass: &mut T, | ||||||
|         state: &mut State<T::TError>, |         state: &mut State<T::TError>, | ||||||
|         scope: &mut Scope<T::Data>, |         scope: &mut Scope<T::Data>, | ||||||
|     ) { |     ) -> PassResult { | ||||||
|         pass.expr(self, PassState::from(state, scope)); |         pass.expr(self, PassState::from(state, scope))?; | ||||||
|  |         Ok(()) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ use crate::{mir::*, util::try_all}; | |||||||
| use VagueType as Vague; | use VagueType as Vague; | ||||||
| 
 | 
 | ||||||
| use super::{ | use super::{ | ||||||
|     pass::{Pass, PassState, ScopeFunction, ScopeVariable}, |     pass::{Pass, PassResult, PassState, ScopeFunction, ScopeVariable}, | ||||||
|     typerefs::TypeRefs, |     typerefs::TypeRefs, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -70,7 +70,7 @@ impl<'t> Pass for TypeCheck<'t> { | |||||||
|     type Data = (); |     type Data = (); | ||||||
|     type TError = ErrorKind; |     type TError = ErrorKind; | ||||||
| 
 | 
 | ||||||
|     fn module(&mut self, module: &mut Module, mut state: TypecheckPassState) { |     fn module(&mut self, module: &mut Module, mut state: TypecheckPassState) -> PassResult { | ||||||
|         let mut defmap = HashMap::new(); |         let mut defmap = HashMap::new(); | ||||||
|         for typedef in &module.typedefs { |         for typedef in &module.typedefs { | ||||||
|             let TypeDefinition { name, kind, meta } = &typedef; |             let TypeDefinition { name, kind, meta } = &typedef; | ||||||
| @ -107,6 +107,7 @@ impl<'t> Pass for TypeCheck<'t> { | |||||||
|             let res = function.typecheck(&self.refs, &mut state.inner()); |             let res = function.typecheck(&self.refs, &mut state.inner()); | ||||||
|             state.ok(res, function.block_meta()); |             state.ok(res, function.block_meta()); | ||||||
|         } |         } | ||||||
|  |         Ok(()) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ use std::{convert::Infallible, iter}; | |||||||
| use crate::{mir::TypeKind, util::try_all}; | use crate::{mir::TypeKind, util::try_all}; | ||||||
| 
 | 
 | ||||||
| use super::{ | use super::{ | ||||||
|     pass::{Pass, PassState}, |     pass::{Pass, PassResult, PassState}, | ||||||
|     r#impl::pick_return, |     r#impl::pick_return, | ||||||
|     typecheck::ErrorKind, |     typecheck::ErrorKind, | ||||||
|     typerefs::{ScopeTypeRefs, TypeRef, TypeRefs}, |     typerefs::{ScopeTypeRefs, TypeRef, TypeRefs}, | ||||||
| @ -32,11 +32,12 @@ impl<'t> Pass for TypeInference<'t> { | |||||||
|     type Data = (); |     type Data = (); | ||||||
|     type TError = ErrorKind; |     type TError = ErrorKind; | ||||||
| 
 | 
 | ||||||
|     fn module(&mut self, module: &mut Module, mut state: TypeInferencePassState) { |     fn module(&mut self, module: &mut Module, mut state: TypeInferencePassState) -> PassResult { | ||||||
|         for function in &mut module.functions { |         for function in &mut module.functions { | ||||||
|             let res = function.infer_types(&self.refs, &mut state.inner()); |             let res = function.infer_types(&self.refs, &mut state.inner()); | ||||||
|             state.ok(res, function.block_meta()); |             state.ok(res, function.block_meta()); | ||||||
|         } |         } | ||||||
|  |         Ok(()) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -14,7 +14,9 @@ fn compiles() { | |||||||
| #[test] | #[test] | ||||||
| fn passes_all_passes() { | fn passes_all_passes() { | ||||||
|     let mut map = Default::default(); |     let mut map = Default::default(); | ||||||
|     let (mut std, _) = compile_std(&mut map); |     let Ok((mut std, _)) = compile_std(&mut map) else { | ||||||
|  |         panic!() | ||||||
|  |     }; | ||||||
| 
 | 
 | ||||||
|     // Needed to pass linker-pass
 |     // Needed to pass linker-pass
 | ||||||
|     std.is_main = true; |     std.is_main = true; | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								reid_src/std_test.reid
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								reid_src/std_test.reid
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | 
 | ||||||
|  | import std::print; | ||||||
|  | import std::intdiv; | ||||||
|  | 
 | ||||||
|  | fn main() { | ||||||
|  |     let hello = "hello world"; | ||||||
|  | 
 | ||||||
|  |     print(intdiv(10, 5).quot); | ||||||
|  | 
 | ||||||
|  |     print(hello); | ||||||
|  | 
 | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user