Implement void returns
This commit is contained in:
		
							parent
							
								
									5b59d0689b
								
							
						
					
					
						commit
						be3c415a57
					
				| @ -7,7 +7,7 @@ import std::new_string; | |||||||
| import std::add_num_to_str; | import std::add_num_to_str; | ||||||
| import std::concat_strings; | import std::concat_strings; | ||||||
| 
 | 
 | ||||||
| fn main() -> u8 { | fn main() { | ||||||
|     let mut test = from_str("hello"); |     let mut test = from_str("hello"); | ||||||
| 
 | 
 | ||||||
|     concat_strings(&mut test, from_str(" world")); |     concat_strings(&mut test, from_str(" world")); | ||||||
| @ -21,5 +21,5 @@ fn main() -> u8 { | |||||||
| 
 | 
 | ||||||
|     free_string(&test); |     free_string(&test); | ||||||
| 
 | 
 | ||||||
|     return 8; |     return; | ||||||
| } | } | ||||||
|  | |||||||
| @ -89,7 +89,9 @@ impl mir::Block { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if let Some((_, ret_expr)) = &self.return_expression { |         if let Some((_, ret_expr)) = &self.return_expression { | ||||||
|             allocated.extend(ret_expr.allocate(scope)); |             if let Some(ret_expr) = ret_expr { | ||||||
|  |                 allocated.extend(ret_expr.allocate(scope)); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         allocated |         allocated | ||||||
|  | |||||||
| @ -164,7 +164,7 @@ pub struct StructExpression { | |||||||
| #[derive(Debug, Clone)] | #[derive(Debug, Clone)] | ||||||
| pub struct Block( | pub struct Block( | ||||||
|     pub Vec<BlockLevelStatement>, |     pub Vec<BlockLevelStatement>, | ||||||
|     pub Option<(ReturnType, Expression)>, |     pub Option<(ReturnType, Option<Expression>)>, | ||||||
|     pub TokenRange, |     pub TokenRange, | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| @ -177,7 +177,7 @@ pub enum BlockLevelStatement { | |||||||
|         _i: ImportStatement, |         _i: ImportStatement, | ||||||
|     }, |     }, | ||||||
|     Expression(Expression), |     Expression(Expression), | ||||||
|     Return(ReturnType, Expression), |     Return(ReturnType, Option<Expression>), | ||||||
|     ForLoop(String, TokenRange, Expression, Expression, Block), |     ForLoop(String, TokenRange, Expression, Expression, Block), | ||||||
|     WhileLoop(Expression, Block), |     WhileLoop(Expression, Block), | ||||||
| } | } | ||||||
|  | |||||||
| @ -556,7 +556,7 @@ impl Parse for Block { | |||||||
|         stream.expect(Token::BraceOpen)?; |         stream.expect(Token::BraceOpen)?; | ||||||
| 
 | 
 | ||||||
|         while !matches!(stream.peek(), Some(Token::BraceClose)) { |         while !matches!(stream.peek(), Some(Token::BraceClose)) { | ||||||
|             if let Some((_, e)) = return_stmt.take() { |             if let Some((_, Some(e))) = return_stmt.take() { | ||||||
|                 // Special list of expressions that are simply not warned about,
 |                 // Special list of expressions that are simply not warned about,
 | ||||||
|                 // if semicolon is missing.
 |                 // if semicolon is missing.
 | ||||||
|                 if !matches!(e, Expression(ExpressionKind::IfExpr(_), _)) { |                 if !matches!(e, Expression(ExpressionKind::IfExpr(_), _)) { | ||||||
| @ -697,7 +697,7 @@ impl Parse for BlockLevelStatement { | |||||||
|             }, |             }, | ||||||
|             Some(Token::ReturnKeyword) => { |             Some(Token::ReturnKeyword) => { | ||||||
|                 stream.next(); |                 stream.next(); | ||||||
|                 let exp = stream.parse()?; |                 let exp = stream.parse().ok(); | ||||||
|                 stream.expect(Token::Semi)?; |                 stream.expect(Token::Semi)?; | ||||||
|                 Stmt::Return(ReturnType::Hard, exp) |                 Stmt::Return(ReturnType::Hard, exp) | ||||||
|             } |             } | ||||||
| @ -717,7 +717,7 @@ impl Parse for BlockLevelStatement { | |||||||
|                     if stream.expect(Token::Semi).is_ok() { |                     if stream.expect(Token::Semi).is_ok() { | ||||||
|                         Stmt::Expression(e) |                         Stmt::Expression(e) | ||||||
|                     } else { |                     } else { | ||||||
|                         Stmt::Return(ReturnType::Soft, e) |                         Stmt::Return(ReturnType::Soft, Some(e)) | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -3,8 +3,8 @@ use std::path::PathBuf; | |||||||
| use crate::{ | use crate::{ | ||||||
|     ast::{self}, |     ast::{self}, | ||||||
|     mir::{ |     mir::{ | ||||||
|         self, CustomTypeKey, ModuleMap, NamedVariableRef, SourceModuleId, StmtKind, StructField, |         self, CustomTypeKey, ModuleMap, NamedVariableRef, ReturnKind, SourceModuleId, StmtKind, | ||||||
|         StructType, WhileStatement, |         StructField, StructType, WhileStatement, | ||||||
|     }, |     }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -166,7 +166,11 @@ impl ast::Block { | |||||||
|                     (StmtKind::Expression(e.process(module_id)), e.1) |                     (StmtKind::Expression(e.process(module_id)), e.1) | ||||||
|                 } |                 } | ||||||
|                 ast::BlockLevelStatement::Return(_, e) => { |                 ast::BlockLevelStatement::Return(_, e) => { | ||||||
|                     (StmtKind::Expression(e.process(module_id)), e.1) |                     if let Some(e) = e { | ||||||
|  |                         (StmtKind::Expression(e.process(module_id)), e.1) | ||||||
|  |                     } else { | ||||||
|  |                         panic!(); // Should never happen?
 | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|                 ast::BlockLevelStatement::ForLoop(counter, counter_range, start, end, block) => { |                 ast::BlockLevelStatement::ForLoop(counter, counter_range, start, end, block) => { | ||||||
|                     let counter_var = NamedVariableRef( |                     let counter_var = NamedVariableRef( | ||||||
| @ -249,7 +253,11 @@ impl ast::Block { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         let return_expression = if let Some(r) = &self.1 { |         let return_expression = if let Some(r) = &self.1 { | ||||||
|             Some((r.0.into(), Box::new(r.1.process(module_id)))) |             if let Some(expr) = &r.1 { | ||||||
|  |                 Some((r.0.into(), Some(Box::new(expr.process(module_id))))) | ||||||
|  |             } else { | ||||||
|  |                 Some((ReturnKind::Hard, None)) | ||||||
|  |             } | ||||||
|         } else { |         } else { | ||||||
|             None |             None | ||||||
|         }; |         }; | ||||||
|  | |||||||
| @ -632,12 +632,12 @@ impl FunctionDefinitionKind { | |||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 if let Some(debug) = &scope.debug { |                 if let Some(debug) = &scope.debug { | ||||||
|                     let location = &block |                     if let Some(location) = | ||||||
|                         .return_meta() |                         &block.return_meta().into_debug(scope.tokens, debug.scope) | ||||||
|                         .into_debug(scope.tokens, debug.scope) |                     { | ||||||
|                         .unwrap(); |                         let location = debug.info.location(&debug.scope, *location); | ||||||
|                     let location = debug.info.location(&debug.scope, *location); |                         scope.block.set_terminator_location(location).unwrap(); | ||||||
|                     scope.block.set_terminator_location(location).unwrap(); |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             mir::FunctionDefinitionKind::Extern(_) => {} |             mir::FunctionDefinitionKind::Extern(_) => {} | ||||||
| @ -664,17 +664,25 @@ impl mir::Block { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if let Some((kind, expr)) = &self.return_expression { |         if let Some((kind, expr)) = &self.return_expression { | ||||||
|             let ret = expr.codegen(&mut scope, &mut state.load(true))?; |             if let Some(expr) = expr { | ||||||
|             match kind { |                 let ret = expr.codegen(&mut scope, &mut state.load(true))?; | ||||||
|                 mir::ReturnKind::Hard => { |                 match kind { | ||||||
|                     if let Some(ret) = ret { |                     mir::ReturnKind::Hard => { | ||||||
|                         scope.block.terminate(Term::Ret(ret.instr())).unwrap(); |                         if let Some(ret) = ret { | ||||||
|                     } else { |                             scope.block.terminate(Term::Ret(ret.instr())).unwrap(); | ||||||
|                         scope.block.terminate(Term::RetVoid).unwrap(); |                         } else { | ||||||
|  |                             scope.block.terminate(Term::RetVoid).unwrap(); | ||||||
|  |                         } | ||||||
|  |                         Ok(None) | ||||||
|                     } |                     } | ||||||
|                     Ok(None) |                     mir::ReturnKind::Soft => Ok(ret), | ||||||
|                 } |                 } | ||||||
|                 mir::ReturnKind::Soft => Ok(ret), |             } else { | ||||||
|  |                 match kind { | ||||||
|  |                     mir::ReturnKind::Hard => scope.block.terminate(Term::RetVoid).unwrap(), | ||||||
|  |                     mir::ReturnKind::Soft => {} | ||||||
|  |                 } | ||||||
|  |                 Ok(None) | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             Ok(None) |             Ok(None) | ||||||
|  | |||||||
| @ -142,9 +142,15 @@ impl Display for Block { | |||||||
|             write!(inner_f, "{}", statement)?; |             write!(inner_f, "{}", statement)?; | ||||||
|         } |         } | ||||||
|         if let Some(ret) = &self.return_expression { |         if let Some(ret) = &self.return_expression { | ||||||
|  |             let ret_fmt = if let Some(ret) = &ret.1 { | ||||||
|  |                 format!("{}", ret) | ||||||
|  |             } else { | ||||||
|  |                 String::from("void") | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|             match ret.0 { |             match ret.0 { | ||||||
|                 ReturnKind::Hard => writeln!(inner_f, "Return(Hard): {}", ret.1), |                 ReturnKind::Hard => writeln!(inner_f, "Return(Hard): {}", ret_fmt), | ||||||
|                 ReturnKind::Soft => writeln!(inner_f, "Return(Soft): {}", ret.1), |                 ReturnKind::Soft => writeln!(inner_f, "Return(Soft): {}", ret_fmt), | ||||||
|             }?; |             }?; | ||||||
|         } else { |         } else { | ||||||
|             writeln!(inner_f, "No Return")?; |             writeln!(inner_f, "No Return")?; | ||||||
|  | |||||||
| @ -367,7 +367,7 @@ impl StructType { | |||||||
| 
 | 
 | ||||||
| enum BlockReturn<'b> { | enum BlockReturn<'b> { | ||||||
|     Early(&'b Statement), |     Early(&'b Statement), | ||||||
|     Normal(ReturnKind, &'b Expression), |     Normal(ReturnKind, &'b Option<Box<Expression>>), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Block { | impl Block { | ||||||
| @ -394,7 +394,7 @@ impl Block { | |||||||
|     pub fn return_meta(&self) -> Metadata { |     pub fn return_meta(&self) -> Metadata { | ||||||
|         self.return_expression |         self.return_expression | ||||||
|             .as_ref() |             .as_ref() | ||||||
|             .map(|e| e.1 .1) |             .map(|e| e.1.as_ref().map(|e| e.1).unwrap_or(Metadata::default())) | ||||||
|             .or(self.statements.last().map(|s| s.1)) |             .or(self.statements.last().map(|s| s.1)) | ||||||
|             .unwrap_or(self.meta) |             .unwrap_or(self.meta) | ||||||
|     } |     } | ||||||
| @ -420,15 +420,27 @@ impl Block { | |||||||
|         self.return_expression |         self.return_expression | ||||||
|             .as_ref() |             .as_ref() | ||||||
|             .ok_or(ReturnTypeOther::NoBlockReturn(self.meta)) |             .ok_or(ReturnTypeOther::NoBlockReturn(self.meta)) | ||||||
|             .and_then(|(kind, stmt)| Ok((*kind, stmt.return_type(refs, mod_id)?.1))) |             .and_then(|(kind, stmt)| { | ||||||
|  |                 Ok(( | ||||||
|  |                     *kind, | ||||||
|  |                     stmt.as_ref() | ||||||
|  |                         .and_then(|s| s.return_type(refs, mod_id).ok()) | ||||||
|  |                         .map(|s| s.1) | ||||||
|  |                         .unwrap_or(TypeKind::Void), | ||||||
|  |                 )) | ||||||
|  |             }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn backing_var(&self) -> Option<&NamedVariableRef> { |     pub fn backing_var(&self) -> Option<&NamedVariableRef> { | ||||||
|         match self.return_expr().ok()? { |         match self.return_expr().ok()? { | ||||||
|             BlockReturn::Early(statement) => statement.backing_var(), |             BlockReturn::Early(statement) => statement.backing_var(), | ||||||
|             BlockReturn::Normal(kind, expr) => { |             BlockReturn::Normal(kind, expr) => { | ||||||
|                 if kind == ReturnKind::Soft { |                 if let Some(expr) = expr { | ||||||
|                     expr.backing_var() |                     if kind == ReturnKind::Soft { | ||||||
|  |                         expr.backing_var() | ||||||
|  |                     } else { | ||||||
|  |                         None | ||||||
|  |                     } | ||||||
|                 } else { |                 } else { | ||||||
|                     None |                     None | ||||||
|                 } |                 } | ||||||
|  | |||||||
| @ -328,7 +328,7 @@ impl FunctionDefinition { | |||||||
| pub struct Block { | pub struct Block { | ||||||
|     /// List of non-returning statements
 |     /// List of non-returning statements
 | ||||||
|     pub statements: Vec<Statement>, |     pub statements: Vec<Statement>, | ||||||
|     pub return_expression: Option<(ReturnKind, Box<Expression>)>, |     pub return_expression: Option<(ReturnKind, Option<Box<Expression>>)>, | ||||||
|     pub meta: Metadata, |     pub meta: Metadata, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -462,11 +462,15 @@ impl Block { | |||||||
|                 ReturnKind::Hard => state.scope.return_type_hint.clone(), |                 ReturnKind::Hard => state.scope.return_type_hint.clone(), | ||||||
|                 ReturnKind::Soft => hint_t.cloned(), |                 ReturnKind::Soft => hint_t.cloned(), | ||||||
|             }; |             }; | ||||||
|             let res = expr.typecheck(&mut state, &typerefs, ret_hint_t.as_ref()); |             if let Some(expr) = expr { | ||||||
|             Ok(( |                 let res = expr.typecheck(&mut state, &typerefs, ret_hint_t.as_ref()); | ||||||
|                 *return_kind, |                 Ok(( | ||||||
|                 state.or_else(res, TypeKind::Vague(Vague::Unknown), expr.1), |                     *return_kind, | ||||||
|             )) |                     state.or_else(res, TypeKind::Vague(Vague::Unknown), expr.1), | ||||||
|  |                 )) | ||||||
|  |             } else { | ||||||
|  |                 Ok((*return_kind, TypeKind::Void)) | ||||||
|  |             } | ||||||
|         } else { |         } else { | ||||||
|             Ok((ReturnKind::Soft, TypeKind::Void)) |             Ok((ReturnKind::Soft, TypeKind::Void)) | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -266,8 +266,10 @@ impl Block { | |||||||
| 
 | 
 | ||||||
|         // If there is a return expression, infer it's type
 |         // If there is a return expression, infer it's type
 | ||||||
|         if let Some(ret_expr) = &mut self.return_expression { |         if let Some(ret_expr) = &mut self.return_expression { | ||||||
|             let ret_res = ret_expr.1.infer_types(&mut state, &inner_refs); |             if let Some(expr) = &mut ret_expr.1 { | ||||||
|             state.ok(ret_res, ret_expr.1 .1); |                 let ret_res = expr.infer_types(&mut state, &inner_refs); | ||||||
|  |                 state.ok(ret_res, expr.1); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Fetch the declared return type
 |         // Fetch the declared return type
 | ||||||
|  | |||||||
| @ -17,7 +17,7 @@ use util::assert_err; | |||||||
| 
 | 
 | ||||||
| mod util; | mod util; | ||||||
| 
 | 
 | ||||||
| fn test(source: &str, name: &str, expected_exit_code: i32) { | fn test(source: &str, name: &str, expected_exit_code: Option<i32>) { | ||||||
|     assert_err(assert_err(std::panic::catch_unwind(|| { |     assert_err(assert_err(std::panic::catch_unwind(|| { | ||||||
|         let mut map = Default::default(); |         let mut map = Default::default(); | ||||||
|         let (id, tokens) = assert_err(parse_module(source, name, &mut map)); |         let (id, tokens) = assert_err(parse_module(source, name, &mut map)); | ||||||
| @ -50,7 +50,9 @@ fn test(source: &str, name: &str, expected_exit_code: i32) { | |||||||
|         let executed = Command::new(&out_path).output(); |         let executed = Command::new(&out_path).output(); | ||||||
|         std::fs::remove_file(out_path).unwrap(); |         std::fs::remove_file(out_path).unwrap(); | ||||||
| 
 | 
 | ||||||
|         assert_eq!(expected_exit_code, executed.unwrap().status.code().unwrap()); |         if let Some(expected_exit_code) = expected_exit_code { | ||||||
|  |             assert_eq!(expected_exit_code, executed.unwrap().status.code().unwrap()); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         Ok::<(), ()>(()) |         Ok::<(), ()>(()) | ||||||
|     }))) |     }))) | ||||||
| @ -58,81 +60,125 @@ fn test(source: &str, name: &str, expected_exit_code: i32) { | |||||||
| 
 | 
 | ||||||
| #[test] | #[test] | ||||||
| fn arithmetic_compiles_well() { | fn arithmetic_compiles_well() { | ||||||
|     test(include_str!("../../examples/arithmetic.reid"), "test", 48); |     test( | ||||||
|  |         include_str!("../../examples/arithmetic.reid"), | ||||||
|  |         "test", | ||||||
|  |         Some(48), | ||||||
|  |     ); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn array_structs_compiles_well() { | fn array_structs_compiles_well() { | ||||||
|     test(include_str!("../../examples/array_structs.reid"), "test", 5); |     test( | ||||||
|  |         include_str!("../../examples/array_structs.reid"), | ||||||
|  |         "test", | ||||||
|  |         Some(5), | ||||||
|  |     ); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn array_compiles_well() { | fn array_compiles_well() { | ||||||
|     test(include_str!("../../examples/array.reid"), "test", 3); |     test(include_str!("../../examples/array.reid"), "test", Some(3)); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn borrow_compiles_well() { | fn borrow_compiles_well() { | ||||||
|     test(include_str!("../../examples/borrow.reid"), "test", 17); |     test(include_str!("../../examples/borrow.reid"), "test", Some(17)); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn borrow_hard_compiles_well() { | fn borrow_hard_compiles_well() { | ||||||
|     test(include_str!("../../examples/borrow_hard.reid"), "test", 17); |     test( | ||||||
|  |         include_str!("../../examples/borrow_hard.reid"), | ||||||
|  |         "test", | ||||||
|  |         Some(17), | ||||||
|  |     ); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn cast_compiles_well() { | fn cast_compiles_well() { | ||||||
|     test(include_str!("../../examples/cast.reid"), "test", 6); |     test(include_str!("../../examples/cast.reid"), "test", Some(6)); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn char_compiles_well() { | fn char_compiles_well() { | ||||||
|     test(include_str!("../../examples/char.reid"), "test", 98); |     test(include_str!("../../examples/char.reid"), "test", Some(98)); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn div_mod_compiles_well() { | fn div_mod_compiles_well() { | ||||||
|     test(include_str!("../../examples/div_mod.reid"), "test", 12); |     test( | ||||||
|  |         include_str!("../../examples/div_mod.reid"), | ||||||
|  |         "test", | ||||||
|  |         Some(12), | ||||||
|  |     ); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn fibonacci_compiles_well() { | fn fibonacci_compiles_well() { | ||||||
|     test(include_str!("../../examples/fibonacci.reid"), "test", 1); |     test( | ||||||
|  |         include_str!("../../examples/fibonacci.reid"), | ||||||
|  |         "test", | ||||||
|  |         Some(1), | ||||||
|  |     ); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn float_compiles_well() { | fn float_compiles_well() { | ||||||
|     test(include_str!("../../examples/float.reid"), "test", 1); |     test(include_str!("../../examples/float.reid"), "test", Some(1)); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn hello_world_compiles_well() { | fn hello_world_compiles_well() { | ||||||
|     test(include_str!("../../examples/hello_world.reid"), "test", 8); |     test( | ||||||
|  |         include_str!("../../examples/hello_world.reid"), | ||||||
|  |         "test", | ||||||
|  |         None, | ||||||
|  |     ); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn mutable_compiles_well() { | fn mutable_compiles_well() { | ||||||
|     test(include_str!("../../examples/mutable.reid"), "test", 21); |     test( | ||||||
|  |         include_str!("../../examples/mutable.reid"), | ||||||
|  |         "test", | ||||||
|  |         Some(21), | ||||||
|  |     ); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn ptr_compiles_well() { | fn ptr_compiles_well() { | ||||||
|     test(include_str!("../../examples/ptr.reid"), "test", 5); |     test(include_str!("../../examples/ptr.reid"), "test", Some(5)); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn std_test_compiles_well() { | fn std_test_compiles_well() { | ||||||
|     test(include_str!("../../examples/std_test.reid"), "test", 3); |     test( | ||||||
|  |         include_str!("../../examples/std_test.reid"), | ||||||
|  |         "test", | ||||||
|  |         Some(3), | ||||||
|  |     ); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn strings_compiles_well() { | fn strings_compiles_well() { | ||||||
|     test(include_str!("../../examples/strings.reid"), "test", 5); |     test(include_str!("../../examples/strings.reid"), "test", Some(5)); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn struct_compiles_well() { | fn struct_compiles_well() { | ||||||
|     test(include_str!("../../examples/struct.reid"), "test", 17); |     test(include_str!("../../examples/struct.reid"), "test", Some(17)); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn loops_compiles_well() { | fn loops_compiles_well() { | ||||||
|     test(include_str!("../../examples/loops.reid"), "test", 10); |     test(include_str!("../../examples/loops.reid"), "test", Some(10)); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn ptr_hard_compiles_well() { | fn ptr_hard_compiles_well() { | ||||||
|     test(include_str!("../../examples/ptr_hard.reid"), "test", 0); |     test( | ||||||
|  |         include_str!("../../examples/ptr_hard.reid"), | ||||||
|  |         "test", | ||||||
|  |         Some(0), | ||||||
|  |     ); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn loop_hard_compiles_well() { | fn loop_hard_compiles_well() { | ||||||
|     test(include_str!("../../examples/loop_hard.reid"), "test", 0); |     test( | ||||||
|  |         include_str!("../../examples/loop_hard.reid"), | ||||||
|  |         "test", | ||||||
|  |         Some(0), | ||||||
|  |     ); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn custom_binop_compiles_well() { | fn custom_binop_compiles_well() { | ||||||
|     test(include_str!("../../examples/custom_binop.reid"), "test", 21); |     test( | ||||||
|  |         include_str!("../../examples/custom_binop.reid"), | ||||||
|  |         "test", | ||||||
|  |         Some(21), | ||||||
|  |     ); | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user