09-funcs.ha (1726B)
1 use rt::{compile, exit, exited, EXIT_SUCCESS}; 2 3 fn simple() int = return 69; 4 5 fn addone(x: *int) void = { 6 *x += 1; 7 }; 8 9 fn pointers() void = { 10 let x = 0; 11 addone(&x); 12 assert(x == 1); 13 let y = &addone; 14 y(&x); 15 assert(x == 2); 16 let z = &y; 17 z(&x); 18 assert(x == 3); 19 }; 20 21 fn vafn(expected: []int, values: int...) void = { 22 assert(len(expected) == len(values)); 23 for (let i = 0z; i < len(values); i += 1) { 24 assert(expected[i] == values[i]); 25 }; 26 }; 27 28 fn vaargs() void = { 29 vafn([1, 2, 3], 1, 2, 3); 30 let data = [1, 2, 3]; 31 vafn(data, data...); 32 vafn([]); 33 }; 34 35 let x: int = 42; 36 37 @init fn init() void = { 38 x = 1337; 39 }; 40 41 @init fn init() void = { 42 void; // Should be allowed to have the same name 43 }; 44 45 @fini fn fini() void = { 46 exit(42); // Magic number 47 }; 48 49 @fini fn fini() void = { 50 void; // Should be allowed to have the same name 51 }; 52 53 fn cvafn(n: int, ...) void = { 54 let ap = vastart(); 55 defer vaend(ap); 56 let ap2 = ap; 57 defer vaend(ap2); 58 for (let i = 0; i < n; i += 1) { 59 let arg: int = vaarg(ap); 60 assert(arg == i + 1); 61 }; 62 for (let i = 0; i < n; i += 1) { 63 let arg: int = vaarg(ap2); 64 assert(arg == i + 1); 65 }; 66 }; 67 68 fn cvaargs() void = { 69 cvafn(3, 1, 2, 3); 70 }; 71 72 fn reject() void = { 73 let failures: [_]str = [ 74 // parameter of size 0 75 "fn f(x: void) void = void;", 76 // parameter of undefined size 77 "fn f(x: [*]int) void = void;", 78 // return value of undefined size 79 "fn f(x: int) [*]int = void;", 80 81 "let x: size = size(fn(x: int) int);", 82 "let x: size = align(fn(x: int) int);", 83 ]; 84 85 for (let i = 0z; i < len(failures); i += 1) { 86 assert(compile(failures[i]) as exited != EXIT_SUCCESS); 87 }; 88 }; 89 90 export fn main() void = { 91 assert(simple() == 69); 92 pointers(); 93 vaargs(); 94 cvaargs(); 95 assert(x == 1337); 96 reject(); 97 };