16-defer.ha (1240B)
1 use rt; 2 use rt::{compile, exited, EXIT_SUCCESS}; 3 4 let x: int = 10; 5 6 fn basics() void = { 7 assert(x == 10); 8 defer x = 20; 9 assert(x == 10); 10 if (true) { 11 return; 12 }; 13 defer x = 30; 14 }; 15 16 fn scope() void = { 17 let x = 10; 18 { 19 defer x = 20; 20 assert(x == 10); 21 }; 22 assert(x == 20); 23 }; 24 25 fn loops() void = { 26 let x = 0; 27 for (let i = 0; i < 5; i += 1) { 28 defer x += 1; 29 assert(x == i); 30 }; 31 assert(x == 5); 32 }; 33 34 fn control() void = { 35 let x = 0; 36 for (let i = 0; i < 5; i += 1) { 37 if (true) { 38 continue; 39 }; 40 defer x += 1; 41 }; 42 assert(x == 0); 43 44 for (let i = 0; i < 5; i += 1) { 45 defer x += 1; 46 if (true) { 47 break; 48 }; 49 abort(); 50 }; 51 assert(x == 1); 52 }; 53 54 fn reject() void = { 55 let failures = [ 56 "export fn main() void = defer 0;", 57 "export fn main() void = { if (true) defer 0; };", 58 "export fn main() void = { for (defer 0; true; true) void; };", 59 ]; 60 61 for (let i = 0z; i < len(failures); i += 1) { 62 assert(compile(failures[i]) as exited != EXIT_SUCCESS); 63 }; 64 }; 65 66 fn noreturn() void = { 67 defer x = 30; 68 for (true) { 69 defer x = 20; 70 exit(); 71 }; 72 }; 73 74 @noreturn fn exit() void = { 75 assert(x == 30); 76 rt::exit(0); 77 }; 78 79 export fn main() void = { 80 basics(); 81 assert(x == 20); 82 scope(); 83 loops(); 84 control(); 85 reject(); 86 noreturn(); 87 };